处理数据表事件Handling DataTable Events

DataTable 对象提供一系列可以由应用程序处理的事件。The DataTable object provides a series of events that can be processed by an application. 下表描述了 DataTable 事件。The following table describes DataTable events.

EventEvent 描述Description
Initialized 在调用 EndInitDataTable 方法后发生。Occurs after the EndInit method of a DataTable is called. 此事件主要用于支持设计时方案。This event is intended primarily to support design-time scenarios.
ColumnChanged 在成功更改 DataColumn 中的值后发生。Occurs after a value has been successfully changed in a DataColumn.
ColumnChanging 提交 DataColumn 的值后发生。Occurs when a value has been submitted for a DataColumn.
RowChanged 在成功更改 DataColumn 值或 RowStateDataRowDataTable 后发生。Occurs after a DataColumn value or the RowState of a DataRow in the DataTable has been changed successfully.
RowChanging 在提交对 DataColumn 值或 RowStateDataRowDataTable 的更改后发生。Occurs when a change has been submitted for a DataColumn value or the RowState of a DataRow in the DataTable.
RowDeleted DataRow 中的 DataTable 已标记为 Deleted 后发生。Occurs after a DataRow in the DataTable has been marked as Deleted.
RowDeleting DataRow 中的 DataTable 标记为 Deleted 前发生。Occurs before a DataRow in the DataTable is marked as Deleted.
TableCleared 在对 ClearDataTable 方法的调用已成功清除每个 DataRow 后发生。Occurs after a call to the Clear method of the DataTable has successfully cleared every DataRow.
TableClearing 在调用 Clear 方法后,开始执行 Clear 操作前发生。Occurs after the Clear method is called but before the Clear operation begins.
TableNewRow 在对 DataRowNewRow 方法的调用创建了新 DataTable 后发生。Occurs after a new DataRow is created by a call to the NewRow method of the DataTable.
Disposed DataTableDisposed 时发生。Occurs when the DataTable is Disposed. MarshalByValueComponent 继承。Inherited from MarshalByValueComponent.

备注

添加或删除行的大多数操作不会引发 ColumnChangedColumnChanging 事件。Most operations that add or delete rows do not raise the ColumnChanged and ColumnChanging events. 但是,当要读取的 XML 文档为 ReadXml 时,除非将 ColumnChanged 设置为 ColumnChangingXmlReadMode,否则 DiffGram 方法会引发 AutoDiffGram 事件。However, the ReadXml method does raise ColumnChanged and ColumnChanging events, unless the XmlReadMode is set to DiffGram or is set to Auto when the XML document being read is a DiffGram.

警告

如果在从中引发 DataSet 事件的 RowChanged 中修改数据,则会发生数据损坏。Data corruption can occur if data is modified in a DataSet from which the RowChanged event is raised. 出现这类数据损坏并不会引发任何异常。No exception will be raised if such data corruption occurs.

Constraints 属性包含 ConstraintCollection 实例。The Constraints property holds a ConstraintCollection instance. ConstraintCollection 类会公开 CollectionChanged 事件。The ConstraintCollection class exposes a CollectionChanged event. ConstraintCollection 中添加、修改约束,或从中删除约束时,会激发此事件。This event fires when a constraint is added, modified, or removed from the ConstraintCollection.

Columns 属性包含 DataColumnCollection 实例。The Columns property holds a DataColumnCollection instance. DataColumnCollection 类会公开 CollectionChanged 事件。The DataColumnCollection class exposes a CollectionChanged event. DataColumn 中添加、修改或从中删除 DataColumnCollection 时,会激发此事件。This event fires when a DataColumn is added, modified, or removed from the DataColumnCollection. 导致激发此事件的修改包括更改列的名称、类型、表达式或序号位置。Modifications that cause the event to fire include changes to the name, type, expression or ordinal position of a column.

TablesDataSet 属性包含 DataTableCollection 实例。The Tables property of a DataSet holds a DataTableCollection instance. DataTableCollection 类会公开 CollectionChangedCollectionChanging 事件。The DataTableCollection class exposes both a CollectionChanged and a CollectionChanging event. DataTable 中添加或从中删除 DataSet 时,会激发这两个事件。These events fire when a DataTable is added to or removed from the DataSet.

更改 DataRows 还会触发已关联 DataView 的事件。Changes to DataRows can also trigger events for an associated DataView. DataView 类会公开 ListChanged 事件,当 DataColumn 值发生更改或视图的撰写或排序顺序发生更改时会激发此事件。The DataView class exposes a ListChanged event that fires when a DataColumn value changes or when the composition or sort order of the view changes. DataRowView 类会公开 PropertyChanged 事件,当关联的 DataColumn 值发生更改时会激发此事件。The DataRowView class exposes a PropertyChanged event that fires when an associated DataColumn value changes.

操作顺序Sequence of Operations

下面是添加、修改或删除 DataRow 时所执行操作的顺序:Here is the sequence of operations that occur when a DataRow is added, modified, or deleted:

  1. 创建建议的记录并应用任何更改。Create the proposed record and apply any changes.

  2. 检查非表达式列的约束。Check constraints for non-expression columns.

  3. 如适用,引发 RowChangingRowDeleting 事件。Raise the RowChanging or RowDeleting events as applicable.

  4. 将建议的记录设置为当前记录。Set the proposed record to be the current record.

  5. 更新任何关联的索引。Update any associated indexes.

  6. 为关联的 ListChanged 对象引发 DataView 事件;为关联的 PropertyChanged 对象引发 DataRowView 事件。Raise ListChanged events for associated DataView objects and PropertyChanged events for associated DataRowView objects.

  7. 计算所有表达式列,但延迟检查对这些列的任何约束。Evaluate all expression columns, but delay checking any constraints on these columns.

  8. 为关联的 ListChanged 对象引发 DataView 事件;为受表达式列计算影响的 PropertyChanged 对象引发 DataRowView 事件。Raise ListChanged events for associated DataView objects and PropertyChanged events for associated DataRowView objects affected by the expression column evaluations.

  9. 如适用,引发 RowChangedRowDeleted 事件。Raise RowChanged or RowDeleted events as applicable.

  10. 检查对表达式列的约束。Check constraints on expression columns.

备注

更改表达式列绝不会引发 DataTable 事件。Changes to expression columns never raise DataTable events. 更改表达式列只会引发 DataViewDataRowView 事件。Changes to expression columns only raise DataView and DataRowView events. 表达式列可与多个其他列存在相关性,并且在单个 DataRow 操作期间可计算多次。Expression columns can have dependencies on multiple other columns, and can be evaluated multiple times during a single DataRow operation. 每个表达式计算都可引发事件,并且当表达式列受影响时,单个 DataRow 操作可引发多个 ListChangedPropertyChanged 事件,其中可能包括同一表达式列的多个事件。Each expression evaluation raises events, and a single DataRow operation can raise multiple ListChanged and PropertyChanged events when expression columns are affected, possibly including multiple events for the same expression column.

警告

请勿在 NullReferenceException 事件处理程序中引发 RowChangedDo not throw a NullReferenceException within the RowChanged event handler. 如果在 NullReferenceExceptionRowChanged 事件中引发了 DataTableDataTable 将被损坏。If a NullReferenceException is thrown within the RowChanged event of a DataTable, then the DataTable will be corrupted.

示例Example

下面的示例演示如何为 RowChangedRowChangingRowDeletedRowDeletingColumnChangedColumnChangingTableNewRowTableClearedTableClearing 事件创建事件处理程序。The following example demonstrates how to create event handlers for the RowChanged, RowChanging, RowDeleted, RowDeleting, ColumnChanged, ColumnChanging, TableNewRow, TableCleared, and TableClearing events. 在激发每个事件处理程序时,都会在控制台窗口中显示相关输出。Each event handler displays output in the console window when it is fired.

static void DataTableEvents()
{
    DataTable table = new DataTable("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 += new DataRowChangeEventHandler(Row_Changed);

    // Add a RowChanging event handler.
    table.RowChanging += new DataRowChangeEventHandler(Row_Changing);

    // Add a RowDeleted event handler.
    table.RowDeleted += new DataRowChangeEventHandler(Row_Deleted);

    // Add a RowDeleting event handler.
    table.RowDeleting += new DataRowChangeEventHandler(Row_Deleting);

    // Add a ColumnChanged event handler.
    table.ColumnChanged += new
        DataColumnChangeEventHandler(Column_Changed);

    // Add a ColumnChanging event handler.
    table.ColumnChanging += new
        DataColumnChangeEventHandler(Column_Changing);

    // Add a TableNewRow event handler.
    table.TableNewRow += new
        DataTableNewRowEventHandler(Table_NewRow);

    // Add a TableCleared event handler.
    table.TableCleared += new
        DataTableClearEventHandler(Table_Cleared);

    // Add a TableClearing event handler.
    table.TableClearing += new
        DataTableClearEventHandler(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();
}

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

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

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

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

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

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

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

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

private 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

请参阅See also