DataTable Events

Similar to many of the objects in the .NET Framework, the DataTable exposes a set of that can be captured and handled. It can be very useful to handle the DataTable event, for case in point, we can use the events to update the user interface, or to validate edits, updates, or deletes before they are dedicated. The DataTable object provides a series of events that can be processed by an application. The following table describes DataTable events.

Event Description
ColumnChanged Occurs when a value has been inserted successfully into a column.
ColumnChanging Occurs when a value has been submitted for a column.
RowChanged Occurs after a row in the table has been edited successfully.
RowChanging Occurs when a row in the table is changing.
RowDeleted Occurs after a row in the table has been marked as deleted.
RowDeleting Occurs prior to a row in the table being marked as deleted. (occurs after as DataTow sucessfully deleted)

The following example creates four events: OnColumnChanged, OnColumnChanging, OnRowChanged, and OnRowChanging. Each of these events occurs when a column or row changes.

currentTable.ColumnChanged += new DataColumnChangeEventHandler(OnColumnChanged);
currentTable.ColumnChanging +=
new
DataColumnChangeEventHandler(OnColumnChanging);
currentTable.RowChanged += new
DataRowChangeEventHandler(OnRowChanged);
currentTable.RowChanging +=
new
DataRowChangeEventHandler(OnRowChanging);
protected static void OnColumnChanged(object
sender, DataColumnChangeEventArgs args)
{
Console.Write(" ColumnChanged: ");
Console.Write(args.Column.ColumnName + " changed to '" + args.ProposedValue + "'\n");
}
protected static void OnColumnChanging(object
sender, DataColumnChangeEventArgs args)
{
Console.Write("ColumnChanging: ");
Console.Write(args.Column.ColumnName + " equals '" + args.Row[args.Column] + ', changing to '" + args.ProposedValue + "'\n");
protected
static void OnRowChanging(object sender, DataRowChangeEventArgs args)
{
if (args.Action != DataRowAction.Nothing)
Console.WriteLine(" RowChanging: Action = " + args.Action + ", CustID = " + args.Row
"CustID"]);
}
protected static void OnRowChanged(object
sender, DataRowChangeEventArgs args)
{
if
(args.Action != DataRowAction.Nothing)
Console.WriteLine(" RowChanged: Action = " + args.Action + ", CustID = " + args.Row
"CustID"]);

For instance we can see these events are paired; one of them throws out when something is happening, and one fires after the first finishes successfully. We can handle these events by creating an event handler for each event. The event handlers take arguments as specified for the event. To add the event handler to an instance of a DataTable, create a new event handler object, and pass in the name of the method that will handle the event.

private void ColumnChangingHandler(Object sender, DataColumnChangeEventArgs e)
{
//
// process lines
//
}
// Add ColumnChanging and ColumnChanged Event Handlers
FirsDataTables.ColumnChanging += new

DataColumnChangeEventHandler(ColumnChangingHandler);

Each of the DataTable events works in the same fashion. The ColumnChanging and ColumnChanged events take a DataColumnChangeEventArgs object, while the other events take a DataRowChangeEventArgs object.
Here is an example for DataTable events:

// ASPX file first
<%@ Page Inherits="DataTableExample" src="DataTableExample.cs" %>
<HTML>
<
BODY
>
<
FORM runat="server" ID
="Form2">
<
TABLE CellPadding="4" CellSpacing="0" Brider="0">
<TR>
<
TD VALIGN
="TOP">
<
H3
>
Products Table
</H3
>
<
asp:DataGrid runat="server" id="productGrid" CellPadding="4" CellSpacing="0" BorderWidth="1" Gridlines="Horizontal" Font-Names="Verdana, Arial, sans-serif" Font-Size="x-small"
HeaderStyle-Font-Bold="True" OnEditCommand="DataGrid_OnEditCommand" OnCancelCommand="DataGrid_OnCancelCommand" OnUpdateCommand="DataGrid_OnUpdateCommand" OnDeleteCommand
="DataGrid_OnDeleteCommand">
<
Columns
>
<asp:ButtonColumn Text="Delete" CommandName="Delete"
/>
<
asp:EditCommandColumn EditText="Edit" CancelText="Cancel"

UpdateText="Update"
/>
</
Columns
>
</
asp:DataGrid
>
</
TD
>
<
TD VALIGN
="TOP">
<
H3
>
DataTable Events List
</H3><asp:Label runat="server" id="EventsList" Font-Names="Verdana, Arial, sans-serif"
Font-Size="x-small"
/>
</
TD
>
</
TR
>
</
TABLE
>
</
FORM
>
</
BODY
>
</
HTML>

And here is C# code for this aspx file (Codebehind):

using System;
using
System.Data;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
public class
DataTableExample : Page
{
//Declare the DataTable object at the class level
protected
DataTable myDataTable;
//Map the Web Form server controls
protected
DataGrid productGrid, categoryGrid;
protected
Label EventsList;
private void
MakeData()
{
myDataTable = (DataTable)Cache.Get("myDataTable");
//If myDataTable is not in the cache, create it
if(myDataTable == null
)
{
myDataTable =
new
DataTable("Products");
//Build the Products schema
myDataTable.Columns.Add("ID",
Type.GetType("System.Int32"));
myDataTable.Columns.Add("Name",
Type.GetType("System.String"));
myDataTable.Columns.Add("Category",
Type.GetType("System.Int32"));
//Set up the ID column as the PrimaryKey
DataColumn[] pk = new
DataColumn[1];
pk[0] = myDataTable.Columns["ID"];
myDataTable.PrimaryKey = pk;
myDataTable.Columns["ID"].AutoIncrement =
true
;
myDataTable.Columns["ID"].AutoIncrementSeed = 1;
myDataTable.Columns["ID"].ReadOnly =
true
;
DataRow tempRow;
//Populate the Products table with 10 cars
for(int
i = 0; i < 10; i++)
{
//Make every other car a Caterham Seven de Dion
if
(Math.IEEERemainder(i,2) == 0)
{
tempRow = myDataTable.NewRow();
tempRow["Name"] = "Caterham Seven de Dion #" +
i.ToString();
tempRow["Category"] = 1;
myDataTable.Rows.Add(tempRow);
}
else
{
tempRow = myDataTable.NewRow();
tempRow["Name"] = "Dodge Viper #" + i.ToString();
empRow["Category"] = 2;
myDataTable.Rows.Add(tempRow);
}
}
Cache.Insert("myDataTable", myDataTable);
}
}
private void
BindData()
{
//Get the DataSet
MakeData();
//Set the DataGrid.DataSource properties
productGrid.DataSource = myDataTable;
//Bind the DataGrid
productGrid.DataBind();
}
protected void Page_Load(object
sender, EventArgs e)
{
if
(!Page.IsPostBack)
{
//Start with a fresh DataTable
Cache.Remove("myDataTable");
}
//Create a new DataSet by calling the MakeData method
MakeData();
myDataTable.ColumnChanging +=
new
DataColumnChangeEventHandler(ColumnChangingHandler);
myDataTable.ColumnChanged +=
new
DataColumnChangeEventHandler(ColumnChangedHandler);
//Add RowChanging and RowChanged Event Handlers
myDataTable.RowChanging +=
new
DataRowChangeEventHandler(RowChangingHandler);
myDataTable.RowChanged +=
new
DataRowChangeEventHandler(RowChangedHandler);
//Add RowDeleting and RowDeleted Event Handlers
myDataTable.RowDeleting +=
new
DataRowChangeEventHandler(RowDeletingHandler);
myDataTable.RowDeleted +=
new
DataRowChangeEventHandler(RowDeletedHandler);
if
(!Page.IsPostBack)
BindData();
}
}
//*********************************************************************//
//********************** DataColumn Event Handlers ********************//
//*********************************************************************//
private void ColumnChangingHandler(object
sender,
DataColumnChangeEventArgs e)
{
EventsList.Text += String.Format(
"<B>ColumnChanging Handler</B><BR>" +
"&nbsp;&nbsp;Column: {0}<BR>",
e.Column.ColumnName);
string
propValue = e.ProposedValue.ToString().ToLower();
if
((e.Column.ColumnName == "Name")
&& (propValue.IndexOf("pinto") > -1))
{
throw(new
System.Exception(
"Pintos are not allowed on this list."));
}
else
{
EventsList.Text += String.Format(
"&nbsp;&nbsp;Changing <I>{0}</I> " +
"to <I>{1}</I><BR>",
e.Row[e.Column.ColumnName],
e.ProposedValue);
}
}
private void ColumnChangedHandler(object
sender,
DataColumnChangeEventArgs e)
{
EventsList.Text += String.Format(
"<FONT COLOR=\"RED\">" +
"<B>ColumnChanged Handler</B></FONT><BR>" +
"&nbsp;&nbsp;Column: {0}<BR>",
e.Column.ColumnName);
EventsList.Text += String.Format(
"&nbsp;&nbsp;New Value: {0}<BR>",
e.ProposedValue);
}
//*********************************************************************//
//****************************
DataRow Event Handlers **********************//
//*********************************************************************//
private void RowChangingHandler(object
sender,
DataRowChangeEventArgs e)
{
EventsList.Text += String.Format(
"<B>RowChanging Handler</B><BR>" +
"&nbsp;&nbsp;Row: {0}<BR>",
e.Row["ID"]);
EventsList.Text += String.Format(
"&nbsp;&nbsp;Action: {0}<BR>",
e.Action);
}
private void RowChangedHandler(object
sender,
DataRowChangeEventArgs e)
{
EventsList.Text += String.Format(
"<FONT COLOR=\"RED\"><B>" +"RowChanged Handler</B></FONT><BR>" +

"Row: {0}<BR>",
e.Row["ID"]);
EventsList.Text += String.Format(
"&nbsp;&nbsp;Action: {0}<BR>",
e.Action);
}
private void RowDeletingHandler(object
sender,
DataRowChangeEventArgs e)
{
EventsList.Text += String.Format(
"<B>RowDeleting Handler</B><BR>" +
"Row: {0}<BR>",
e.Row["ID"]);

EventsList.Text += String.Format(
"&nbsp;&nbsp;Action: {0}<BR>",
e.Action);}

private
void RowDeletedHandler(object sender,
DataRowChangeEventArgs e)
{
EventsList.Text += "<FONT COLOR=\"RED\">" +
"<B>RowDeleted Handler</B></FONT><BR>";
EventsList.Text += String.Format("&nbsp;&nbsp;Action: {0}<BR>",
e.Action);
}
//*********************************************************************//
//********************** DataGrid Event Handlers **********************//
//*********************************************************************//
protected void DataGrid_OnEditCommand(object
sender,
DataGridCommandEventArgs e)
{
EventsList.Text = "";
((DataGrid)sender).EditItemIndex = e.Item.ItemIndex;
BindData();
}
protected void DataGrid_OnCancelCommand(object
sender,
DataGridCommandEventArgs e)
{
((DataGrid)sender).EditItemIndex = -1;
BindData();
}
protected void DataGrid_OnUpdateCommand(object
sender,
DataGridCommandEventArgs e)
{EventsList.Text = "";

//Cast an object as the source DataGrid
DataGrid senderGrid = (DataGrid)sender;
//Invoke MakeData() to create the myDataTable object
MakeData();
//Get the edited item values
TextBox Name = (TextBox)e.Item.Cells[3].Controls[0];
TextBox Category = (TextBox)e.Item.Cells[4].Controls[0];
//Get the PrimaryKey column text
string
item = e.Item.Cells[2].Text;
//Get the DataRow from myDataTable
DataRow dr = myDataTable.Rows.Find(Int32.Parse(item));
//Change the DataRow values
//This will raise the ColumnChanging event
try
{
dr[1] = Name.Text;
dr[2] = Int32.Parse(Category.Text);
//Commit the changes to the DataRow
//This will raise the ColumnChanged event
dr.AcceptChanges();
}
catch
(Exception ex)
{
EventsList.Text += "<FONT COLOR=\"RED\"><B>Error: </FONT>" +
ex.Message +
"</B>";
}
//Recache the DataTable
Cache.Insert("myDataTable", myDataTable);
//Bind the DataGrid
senderGrid.EditItemIndex = -1;
BindData();
}
protected void DataGrid_OnDeleteCommand(object
sender,
DataGridCommandEventArgs e) {
EventsList.Text = "";
//Cast an object as the source DataGrid
DataGrid senderGrid = (DataGrid)sender;
//Get the Data and create a DataView to filter
MakeData();
//Get the PrimaryKey column text
string
item = e.Item.Cells[2].Text;
//Get the DataRow from myDataTable
DataRow dr = myDataTable.Rows.Find(Int32.Parse(item));
//Use the Remove() method to delete the row
myDataTable.Rows.Remove(dr);
//Recache the DataSet
Cache.Insert("myDataTable", myDataTable);
//Bind the DataGrid
senderGrid.EditItemIndex = -1;
BindData();
}
}

continue article

Next Recommended Readings