处理数据表事件

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

事件 说明
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 类会公开 CollectionChangedCollectionChanging 事件。 向 DataTable 中添加或从中删除 DataSet 时,会激发这两个事件。

更改 DataRows 还会触发已关联 DataView 的事件。 DataView 类会公开 ListChanged 事件,当 DataColumn 值发生更改或视图的撰写或排序顺序发生更改时会激发此事件。 DataRowView 类会公开 PropertyChanged 事件,当关联的 DataColumn 值发生更改时会激发此事件。

操作顺序

下面是添加、修改或删除 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 操作可引发多个 ListChangedPropertyChanged 事件,其中可能包括同一表达式列的多个事件。

警告

请勿在 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 = new DataColumn[] { 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={0}; action={1}",
        e.Row["name"], e.Action);

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

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

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

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

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

static void Table_NewRow(object sender,
    DataTableNewRowEventArgs e) =>
    Console.WriteLine("Table_NewRow Event: RowState={0}",
        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

请参阅