處理 DataTable 的事件

DataTable 物件提供一系列可由應用程式處理的事件。 下表說明 DataTable 事件。

事件 描述
Initialized 發生在呼叫 EndInitDataTable 方法之後。 這個事件主要是為了支援設計階段案例而提供。
ColumnChanged 發生在成功變更 DataColumn 中的值之後。
ColumnChanging 發生在 DataColumn 的值送出之時。
RowChanged 發生在 DataColumn 中的 RowState 值或 DataRowDataTable 成功變更之後。
RowChanging 發生在 DataColumn 中的 RowState 值或DataRowDataTable 變更送出之時。
RowDeleted 發生在 DataRow 中的 DataTable 標記為 Deleted 之後。
RowDeleting 發生在 DataRow 中的 DataTable 標記為 Deleted 之前。
TableCleared 發生在 ClearDataTable 方法成功清除每個 DataRow 之後。
TableClearing 發生在呼叫 Clear 方法之後,但在 Clear 作業開始之前。
TableNewRow 發生在藉由呼叫 DataRowNewRow 方法而建立新的 DataTable 之後。
Disposed 發生在 DataTableDisposed 時。 繼承自 MarshalByValueComponent

注意

大多數加入或刪除資料列的作業都不會引發 ColumnChangedColumnChanging 事件。 不過,ReadXml 方法不會引發 ColumnChangedColumnChanging 事件,除非正在讀取的 XML 文件是 XmlReadMode,而 DiffGram 是設為 AutoDiffGram

警告

如果從中引發 DataSet 事件的 RowChanged 已修改了資料,就可能會發生資料損毀。 如果發生這類資料損毀,就不會引發任何例外狀況 (Exception)。

Constraints 屬性會保存 ConstraintCollection 執行個體 (Instance)。 ConstraintCollection 類別會公開 CollectionChanged 事件。 從 ConstraintCollection 加入、修改或移除條件約束 (Constraint) 時,就會引發這個事件。

Columns 屬性會保存 DataColumnCollection 執行個體 (Instance)。 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 事件內部擲回 DataTable,將會損毀 DataTable

範例

下列範例示範如何建立 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

另請參閱