Creating a web control to insert, update, delete and display data.
Download code
Download BuilderEditor: A DetailsView webcontrol for ASP.NET 1.x.
Introduction
One common task for web applications is to maintain data. It means, insert,
update, delete and display data. Both .NET 1.x and 2.0 have web controls that
you can use to make this task. DataGrid, DataList, GridView and DetailsView are
some of the web controls that you can use to maintain data. In the following
article you will see how to create a custom web control that will help you to
maintain data. It is assumed that you already know how to create web controls,
so we will focus our attention in the main points of our web control. You can
download the code for implementation details.
DataCatalog control overview
The DataCatalog web control allows you to display data. You can update or delete
a data record selecting it and then pressing the Update or Delete button,
respectively. Click on the Insert button to add a new data record. To order
data just click a column name and the data will be ordered based on the
selected column.

Figure 1. DataCatalog web control.
The table below has a more detailed technical explanation.
|
Section name |
Description |
| Header |
The DataCatalog web control has a header section that contains the names of the
data columns from our data source. When the user clicks a column name the data
is ordered by the selected data column. |
| Selection column |
At the left of each data record a radio button is displayed to allow the user
to delete or to update the selected data record. |
| Data record content |
Below the header section the content of each data record is displayed. You can
use the DataFieldsFormatString property to give format (e.g. money format) to a
data field value. |
| Command section |
This section contains an Insert, Update and Delete button. When the Insert
button is clicked the user is redirected to the insert web form. When a data
record is selected and the Update button is clicked the user is redirected to
the update web form. When the Delete button is clicked the selected data record
is deleted. |
DataCatalog control properties
The DataCatalog properties have three main purpose: to specify the SQL
sentences to select and delete data, to specify the format to be applied to the
data field values and to specify the web forms used to insert, update and
display record details.

Figure 2. DataCatalog properties.
The following table contains a description of the DataCatalog properties.
|
Property |
Description |
| SelectText |
SQL sentence used to get the data to be displayed by the DataCatalog web
control. |
| OrderByColumnSelectText |
SQL sentence used to order the data based on the selected data column. |
| DeleteText |
SQL sentence used to delete the selected data record. |
| DbConnectionType |
Used to specify if the sql client (SQL server) or OleDb data provider will be
used. |
| DataKeyNames |
Data column names used to identify a data record. Specify the data field
name(s) used as primary key(s). |
| UpdateRedirectUrl |
URL to which the user will be re-directed after click the Update button. |
| InsertRedirectUrl |
URL to which the user will be re-directed after click the Insert button. |
| DetailsRedirectUrl |
URL to which the user will be re-directed after select a data item. |
| DataFieldsFormatString |
String containing the format to be applied to the data fields. For example, the
following value is used to give format to a date and money data columns,
respectively: PURCHASEDATE={0:dd/MM/yyyy}, PRICE={0:c} |
| ColumnsStyleString |
String containing the css-styles to be applied to the columns. |
DataCatalog child controls
The DataCatalog web control is a composite control. Its control hierarchy is the
next: a Table object containing three rows. The first row corresponds to the
header. The second row corresponds to the data to be displayed. The last row
corresponds to the command buttons (Insert, Update, Delete).
Header
The header section is represented by the HeaderItem object. The HeaderItem
object inherits from the DataCatalogItem object which inherits from the
TableRow object.
public class HeaderItem : DataCatalogItem
{
...
}
For each data column a TableCell object is added to the header row. Each
TableCell will contains a LinkButton control that will allow the user to order
the data.
protected override void CreateColumnHierarchy(bool useDataSource, string columnName, bool firstColumn, bool lastColumn)
{
TableCell cell = new TableCell();
base.Cells.Add(cell);
LinkButton link = new LinkButton();
cell.Controls.Add(link);
if (useDataSource)
{
link.Text = columnName;
link.CommandName = "Order";
}
...
}
When the user clicks a LinkButton the HeaderItem bubbles the event to the
DataCatalog web control to order the data based on the selected data column.
protected override bool OnBubbleEvent(object source, EventArgs args)
{
CommandEventArgs args1 = args as CommandEventArgs;
if (args1 != null)
{
OrderByCommandEventArgs args2 = new OrderByCommandEventArgs(source, args1);
base.RaiseBubbleEvent(this, args2);
return true;
}
return false;
}
Body
The body section contains the data. For each data record a radio button is
displayed at the left. At the right the record data is displayed.
The radio buttons section is represented by the SelectionCell object. The
SelectionCell object inherits from the TableCell object.
public class SelectionCell : TableCell
{
...
}
For each data record a new TableRow object is added to the selection cell. Each
TableRow will contains a RadioButton control.
protected override void CreateChildControls()
{
...
for(int i=0; i<this._itemCount; i++)
{
TableRow row = new TableRow();
table.Rows.Add(row);
TableCell cell = new TableCell();
row.Cells.Add(cell);
RadioButton radio = new RadioButton();
cell.Controls.Add(radio);
radio.GroupName = "ItemsGroup";
}
...
}
The record data is represented by the ContentItem object. The ContentItem object
inherits from the DataCatalogItem object which inherits from the TableRow
object.
public class ContentItem : DataCatalogItem
{
...
}
For each data column a TableCell object is added to the content row. The first
TableCell will contains a LinkButton control used to redirect the user to the
DetailsRedirectUrl web form. The next TableCell objects will contain the data
field values.
protected override void CreateColumnHierarchy(bool useDataSource, string columnName, bool firstColumn, bool lastColumn)
{
...
if (firstColumn)
{
LinkButton link = new LinkButton();
cell.Controls.Add(link);
link.CommandName = "Details";
if (useDataSource)
link.Text = this.GetFieldValue(columnName);
}
else if (useDataSource)
cell.Text = this.GetFieldValue(columnName);
...
}
When the user clicks the LinkButton in the first cell the ContentItem bubbles
the event to the DataCatalog web control to redirect the user to the details
web form.
protected override bool OnBubbleEvent(object source, EventArgs args)
{
CommandEventArgs args1 = args as CommandEventArgs;
if (args1 != null)
{
SelectItemEventArgs args2 = new SelectItemEventArgs(source, args1, this);
base.RaiseBubbleEvent(this, args2);
return true;
}
return false;
}
Footer
The footer section is represented by the CommandItem object. The CommandItem
object inherits from the TableRow object.
public class CommandItem : TableRow, INamingContainer
{
...
}
The CommandItem object contains three buttons: Insert, Update and Delete button.
protected override void CreateChildControls()
{
...
Button button = new Button();
cell.Controls.Add(button);
button.CommandName = "Insert";
button.Text = "Insert";
LiteralControl space = new LiteralControl(" ");
cell.Controls.Add(space);
button = new Button();
cell.Controls.Add(button);
button.CommandName = "Update";
button.Text = "Update";
space = new LiteralControl(" ");
cell.Controls.Add(space);
button = new Button();
cell.Controls.Add(button);
button.CommandName = "Delete";
button.Text = "Delete";
}
When the user clicks any button the CommandItem bubbles the event to the
DataCatalog web control to redirect the user to the insert or update web form,
or to delete the selected data record.
protected override bool OnBubbleEvent(object source, EventArgs args)
{
CommandEventArgs args1 = args as CommandEventArgs;
if (args1 != null)
{
DataOperationCommandEventArgs args2 = new DataOperationCommandEventArgs(source, args1);
base.RaiseBubbleEvent(this, args2);
return true;
}
return false;
}
DataCatalog web control
The DataCatalog web control is a composite control. It is composed by the
HeaderItem, SelectionCell, ContentItem and CommandItem objects.
The main two task of the DataCatalog web controls are: create the control
hierarchy and handle the child controls events.
The CreateControlHierarchy method handles the child controls creation. The
HeaderItem and CommandItem are created at the beginning and at the end,
respectively. For each data item in the data source a ContentItem object is
created. A single SelectionCell object is created.
protected virtual void CreateControlHierarchy(bool useDataSource)
{
...
foreach(object dataItem in data)
{
if (columnNames==null)
{
HeaderItem headerItem = new HeaderItem(columnNames, orderByColumnName);
if (useDataSource)
headerItem.DataBind();
this._dataCatalogTable.Rows.Add(headerItem);
}
ContentItem newItem = new ContentItem(columnNames, itemsCount, this.DataFieldsFormat, this.ColumnsStyle);
if (useDataSource)
{
newItem.DataItem = dataItem;
newItem.DataBind();
}
this._dataCatalogTable.Rows.Add(newItem);
itemsCount++;
}
if (itemsCount>0)
{
outerRow.Cells.AddAt(0, new SelectionCell(itemsCount));
outerTable.Rows.Add(new CommandItem());
}
...
}
The DataCatalog web control overrides the OnBubbleEvent event to handle all the
events of the child controls.
protected override bool OnBubbleEvent(object source, EventArgs e)
{
if (e is DataOperationCommandEventArgs)
{
DataOperationCommandEventArgs args = (DataOperationCommandEventArgs)e;
if (args.DataOperation==DataOperation.Delete)
{
DataKey dataKey = this.GetSeletedDataKey();
if (dataKey!=null)
{
this.DbDataExecute.SqlDeleteText = this.DeleteText;
if (this.DbDataExecute.ExecuteDelete(this.GetDataKeyValues(dataKey), null)>0)
this.DataBind();
}
}
else if (args.DataOperation==DataOperation.Insert)
{
this.Context.Response.Redirect(string.Format("{0}?Mode=Add", this.InsertRedirectUrl), true);
}
else if (args.DataOperation==DataOperation.Update)
{
DataKey dataKey = this.GetSeletedDataKey();
if (dataKey!=null)
{
this.Context.Response.Redirect(
string.Format("{0}?Mode=Edit&{1}",
this.UpdateRedirectUrl,
this.BuildSelectDataItemUrlString(this.GetDataKeyValues(dataKey))),
true);
}
}
return true;
}
else if (e is OrderByCommandEventArgs)
{
OrderByCommandEventArgs args = (OrderByCommandEventArgs)e;
if (StringHelper.IsEmpty(this.OrderByColumnSelectText))
throw new Exception("Specify the OrderByColumnSelectText property value.");
this._orderByColumnName = args.ColumnName;
this._orderByEnabled = true;
this.DataBind();
this._orderByColumnName = string.Empty;
this._orderByEnabled = false;
return true;
}
else if (e is SelectItemEventArgs)
{
SelectItemEventArgs args = (SelectItemEventArgs)e;
string urlString = this.BuildSelectDataItemUrlString(
this.GetDataKeyValues(this.DataKeyManager.GetItemAt(args.Item.ItemIndex)));
if (StringHelper.IsEmpty(this.DetailsRedirectUrl))
throw new Exception("Specify the DetailsRedirectUrl property value.");
this.Context.Response.Redirect(
string.Format("{0}?Mode=ReadOnly&{1}",
this.DetailsRedirectUrl, urlString), true);
return true;
}
return false;
}
The following table has a list of the events handled by the DataCatalog web
control.
|
Event |
Description |
| Delete |
The selected record is deleted. The DataKeyNames property is used to get the
values that identify the record to delete. |
| Insert |
Redirects the user to the web form used to insert data. |
| Update |
Redirects the user to the web form used to update data. The DataKeyNames
property is used to generate a query string used to identify the record to
update. |
| Order |
Orders the data by the selected data column. The
OrderByColumnSelectText property is used to order the data. The [COLUMNNAME]
tag is replaced with the name of the selected column. |
| Select |
Redirects the user to the web form used to select data. The DataKeyNames
property is used to generate a query string used to identify the selected
record. |
InsertRedirectUrl, UpdateRedirectUrl and DetailsRedirectUrl properties
We will use the BuilderEditor web control to build the web forms used to
insert, update and display data. The BuilderEditor web control generates the
controls used to insert, update and display data. You can
download a free BuilderEditor developer version.
To create the content of the web forms used to insert, update and display data
we need to do the next:
-
Drag the BuilderEditor web control to the design surface.
-
Then do right-click and select the Property Builder option from the context
menu option.
-
Right-click in the Available fields area and then select the Fields editor
option.
-
Specify the data fields.
-
Select the controls to be used to insert, update and display data.
-
Click Ok to save changes.
-
The input controls to insert, update and display data are generated.
This article has covered the main features of the DataCatalog web control. For
full details download the code. Download the BuilderEditor and read the
documentation for more details about how to use it.
|