处理数据表事件

DataTable 对象提供一系列可由应用程序处理的事件。 下表描述了 DataTable 事件。

事件 / 活动 DESCRIPTION
Initialized 在调用 EndInitDataTable 方法后发生。 此事件主要用于支持设计时方案。
ColumnChanged 在成功更改 DataColumn 中的值后发生。
ColumnChanging 提交 DataColumn 的值后发生。
RowChanged 在成功更改 DataColumn 值或 RowStateDataRowDataTable 后发生。
RowChanging 在提交对 DataColumn 值或 RowStateDataRowDataTable 的更改后发生。
RowDeleted DataRow 中的 DataTable 已标记为 Deleted 后发生。
RowDeleting DataRow 中的 DataTable 标记为 Deleted 前发生。
TableCleared 在对 ClearDataTable 方法的调用已成功清除每个 DataRow 后发生。
TableClearing 在调用 Clear 方法之后,但在 Clear 操作开始之前发生。
TableNewRow 在对 DataRowNewRow 方法的调用创建了新 DataTable 后发生。
Disposed DataTableDisposed 时发生。 从 MarshalByValueComponent 继承。

注释

大多数添加或删除行的操作不会引发 ColumnChangedColumnChanging 事件。 但是,当要读取的 XML 文档为 ReadXml 时,除非将 ColumnChanged 设置为 ColumnChangingXmlReadMode,否则 DiffGram 方法会引发 AutoDiffGram 事件。

警告

如果在从中引发 DataSet 事件的 RowChanged 中修改数据,则会发生数据损坏。 出现这类数据损坏并不会引发任何异常。

Constraints 属性保存一个 ConstraintCollection 实例。 ConstraintCollection 类公开了一个 CollectionChanged 事件。 当从 ConstraintCollection 中添加、修改或删除约束时,将触发此事件。

Columns 属性保存一个 DataColumnCollection 实例。 DataColumnCollection 类公开了一个 CollectionChanged 事件。 此事件在 DataColumn 中添加、修改或删除 DataColumnCollection 时触发。 导致激发此事件的修改包括更改列的名称、类型、表达式或序号位置。

TablesDataSet属性包含DataTableCollection实例。 该 DataTableCollection 类同时公开一个 CollectionChanged 和一个 CollectionChanging 事件。 当 DataTable 被添加到 DataSet 或从 DataSet 中删除时,将触发这些事件。

更改 DataRows 也可以触发关联的 DataView事件。 该 DataView 类公开了一个 ListChanged 事件,该事件在值更改或 DataColumn 视图的组合或排序顺序发生更改时触发。 DataRowView 类公开了一个事件,该事件在关联的 PropertyChanged 值发生更改时触发。

操作顺序

下面是添加、修改或删除DataRow时发生的操作序列:

  1. 创建建议的记录并应用任何更改。

  2. 检查非表达式列的约束。

  3. 如适用,引发 RowChangingRowDeleting 事件。

  4. 将建议的记录设置为当前记录。

  5. 更新任何关联的索引。

  6. 为关联的ListChanged对象引发DataView事件,并为关联的PropertyChanged对象引发DataRowView事件。

  7. 评估所有表达式列,但延迟验证这些列上的任何约束条件。

  8. 为关联的 ListChanged 对象引发 DataView 事件;为受表达式列计算影响的 PropertyChanged 对象引发 DataRowView 事件。

  9. 如适用,引发 RowChangedRowDeleted 事件。

  10. 检查表达式列的约束。

注释

对表达式列的更改永远不会引发 DataTable 事件。 对表达式列的更改仅引发 DataViewDataRowView 事件。 表达式列可与多个其他列存在相关性,并且在单个 DataRow 操作期间可计算多次。 每个表达式计算都会引发事件,单个 DataRow 作可以在表达式列受到影响时引发多个 ListChanged 事件和 PropertyChanged 事件,可能包括同一表达式列的多个事件。

警告

不要在NullReferenceException事件处理程序中抛出RowChanged。 如果在 NullReferenceExceptionRowChanged 事件中引发了 DataTableDataTable 将被损坏。

示例:

以下示例演示如何为RowChangedRowChangingRowDeletedRowDeletingColumnChangedColumnChangingTableNewRowTableClearedTableClearing事件创建事件处理程序。 触发时,每个事件处理程序都会在控制台窗口中显示输出。

static void DataTableEvents()
{
    DataTable table = new("Customers");
    // Add two columns, id and name.
    table.Columns.Add("id", typeof(int));
    table.Columns.Add("name", typeof(string));

    // Set the primary key.
    table.Columns["id"].Unique = true;
    table.PrimaryKey = [table.Columns["id"]];

    // Add a RowChanged event handler.
    table.RowChanged += Row_Changed;

    // Add a RowChanging event handler.
    table.RowChanging += Row_Changing;

    // Add a RowDeleted event handler.
    table.RowDeleted += Row_Deleted;

    // Add a RowDeleting event handler.
    table.RowDeleting += Row_Deleting;

    // Add a ColumnChanged event handler.
    table.ColumnChanged += Column_Changed;

    // Add a ColumnChanging event handler.
    table.ColumnChanging += Column_Changing;

    // Add a TableNewRow event handler.
    table.TableNewRow += Table_NewRow;

    // Add a TableCleared event handler.
    table.TableCleared += Table_Cleared;

    // Add a TableClearing event handler.
    table.TableClearing += Table_Clearing;

    // Add a customer.
    DataRow row = table.NewRow();
    row["id"] = 1;
    row["name"] = "Customer1";
    table.Rows.Add(row);

    table.AcceptChanges();

    // Change the customer name.
    table.Rows[0]["name"] = "ChangedCustomer1";

    // Delete the row.
    table.Rows[0].Delete();

    // Clear the table.
    table.Clear();
}

static void Row_Changed(object sender, DataRowChangeEventArgs e) =>
    Console.WriteLine($"Row_Changed Event: name={e.Row["name"]}; action={e.Action}");

static void Row_Changing(object sender, DataRowChangeEventArgs e) =>
    Console.WriteLine($"Row_Changing Event: name={e.Row["name"]}; action={e.Action}");

static void Row_Deleted(object sender, DataRowChangeEventArgs e) =>
    Console.WriteLine($"Row_Deleted Event: name={e.Row["name", DataRowVersion.Original]}; action={e.Action}");

static void Row_Deleting(object sender,
DataRowChangeEventArgs e) =>
    Console.WriteLine($"Row_Deleting Event: name={e.Row["name"]}; action={e.Action}");

static void Column_Changed(object sender, DataColumnChangeEventArgs e) =>
    Console.WriteLine($"Column_Changed Event: ColumnName={e.Column.ColumnName}; RowState={e.Row.RowState}");

static void Column_Changing(object sender, DataColumnChangeEventArgs e) =>
    Console.WriteLine($"Column_Changing Event: ColumnName={e.Column.ColumnName}; RowState={e.Row.RowState}");

static void Table_NewRow(object sender,
    DataTableNewRowEventArgs e) =>
    Console.WriteLine($"Table_NewRow Event: RowState={e.Row.RowState.ToString()}");

static void Table_Cleared(object sender, DataTableClearEventArgs e) =>
    Console.WriteLine("Table_Cleared Event: TableName={0}; Rows={1}",
        e.TableName, e.Table.Rows.Count.ToString());

static void Table_Clearing(object sender, DataTableClearEventArgs e) =>
    Console.WriteLine("Table_Clearing Event: TableName={0}; Rows={1}",
        e.TableName, e.Table.Rows.Count.ToString());
Private Sub DataTableEvents()

    Dim table As New DataTable("Customers")
    ' Add two columns, id and name.
    table.Columns.Add("id", Type.GetType("System.Int32"))
    table.Columns.Add("name", Type.GetType("System.String"))

    ' Set the primary key.
    table.Columns("id").Unique = True
    table.PrimaryKey = New DataColumn() {table.Columns("id")}

    ' Add a RowChanged event handler.
    AddHandler table.RowChanged, _
           New DataRowChangeEventHandler(AddressOf Row_Changed)

    ' Add a RowChanging event handler.
    AddHandler table.RowChanging, _
           New DataRowChangeEventHandler(AddressOf Row_Changing)

    ' Add a RowDeleted event handler.
    AddHandler table.RowDeleted, New _
           DataRowChangeEventHandler(AddressOf Row_Deleted)

    ' Add a RowDeleting event handler.
    AddHandler table.RowDeleting, New _
           DataRowChangeEventHandler(AddressOf Row_Deleting)

    ' Add a ColumnChanged event handler.
    AddHandler table.ColumnChanged, _
           New DataColumnChangeEventHandler(AddressOf Column_Changed)

    ' Add a ColumnChanging event handler for the table.
    AddHandler table.ColumnChanging, New _
           DataColumnChangeEventHandler(AddressOf Column_Changing)

    ' Add a TableNewRow event handler.
    AddHandler table.TableNewRow, New _
           DataTableNewRowEventHandler(AddressOf Table_NewRow)

    ' Add a TableCleared event handler.
    AddHandler table.TableCleared, New _
           DataTableClearEventHandler(AddressOf Table_Cleared)

    ' Add a TableClearing event handler.
    AddHandler table.TableClearing, New _
           DataTableClearEventHandler(AddressOf Table_Clearing)

    ' Add a customer.
    Dim row As DataRow = table.NewRow()
    row("id") = 1
    row("name") = "Customer1"
    table.Rows.Add(row)

    table.AcceptChanges()

    ' Change the customer name.
    table.Rows(0).Item("name") = "ChangedCustomer1"

    ' Delete the row.
    table.Rows(0).Delete()

    ' Clear the table.
    table.Clear()
End Sub


Private Sub Row_Changed(ByVal sender As Object, _
    ByVal e As DataRowChangeEventArgs)
    Console.WriteLine("Row_Changed Event: name={0}; action={1}", _
     e.Row("name"), e.Action)
End Sub

Private Sub Row_Changing(ByVal sender As Object, _
    ByVal e As DataRowChangeEventArgs)
    Console.WriteLine("Row_Changing Event: name={0}; action={1}", _
     e.Row("name"), e.Action)
End Sub

Private Sub Row_Deleted(ByVal sender As Object, _
    ByVal e As DataRowChangeEventArgs)
    Console.WriteLine("Row_Deleted Event: name={0}; action={1}", _
     e.Row("name", DataRowVersion.Original), e.Action)
End Sub

Private Sub Row_Deleting(ByVal sender As Object, _
    ByVal e As DataRowChangeEventArgs)
    Console.WriteLine("Row_Deleting Event: name={0}; action={1}", _
       e.Row("name"), e.Action)
End Sub

Private Sub Column_Changed(ByVal sender As Object, _
    ByVal e As DataColumnChangeEventArgs)
    Console.WriteLine("Column_Changed Event: ColumnName={0}; RowState={1}", _
       e.Column.ColumnName, e.Row.RowState)
End Sub

Private Sub Column_Changing(ByVal sender As Object, _
    ByVal e As DataColumnChangeEventArgs)
    Console.WriteLine("Column_Changing Event: ColumnName={0}; RowState={1}", _
       e.Column.ColumnName, e.Row.RowState)
End Sub

Private Sub Table_NewRow(ByVal sender As Object, _
ByVal e As DataTableNewRowEventArgs)
    Console.WriteLine("Table_NewRow Event: RowState={0}", _
       e.Row.RowState.ToString())
End Sub

Private Sub Table_Cleared(ByVal sender As Object, _
    ByVal e As DataTableClearEventArgs)
    Console.WriteLine("Table_Cleared Event: TableName={0}; Rows={1}", _
       e.TableName, e.Table.Rows.Count.ToString())
End Sub

Private Sub Table_Clearing(ByVal sender As Object, _
    ByVal e As DataTableClearEventArgs)
    Console.WriteLine("Table_Clearing Event: TableName={0}; Rows={1}", _
       e.TableName, e.Table.Rows.Count.ToString())
End Sub

另请参阅