DataTable Events in C#

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();
}
}

In this article, we learned the DataTable class events and how to implement them in a C# application. A DataAdapter is a major component of ADO.NET. 

Next >> ADO.NET DataAdapter Using C#


Similar Articles