處理 DataTable 的事件
DataTable 物件提供一系列可由應用程式處理的事件。 下表說明 DataTable
事件。
事件 | 描述 |
---|---|
Initialized | 發生在呼叫 EndInit 的 DataTable 方法之後。 這個事件主要是為了支援設計階段案例而提供。 |
ColumnChanged | 發生在成功變更 DataColumn 中的值之後。 |
ColumnChanging | 發生在 DataColumn 的值送出之時。 |
RowChanged | 發生在 DataColumn 中的 RowState 值或 DataRow 的 DataTable 成功變更之後。 |
RowChanging | 發生在 DataColumn 中的 RowState 值或DataRow 的 DataTable 變更送出之時。 |
RowDeleted | 發生在 DataRow 中的 DataTable 標記為 Deleted 之後。 |
RowDeleting | 發生在 DataRow 中的 DataTable 標記為 Deleted 之前。 |
TableCleared | 發生在 Clear 的 DataTable 方法成功清除每個 DataRow 之後。 |
TableClearing | 發生在呼叫 Clear 方法之後,但在 Clear 作業開始之前。 |
TableNewRow | 發生在藉由呼叫 DataRow 的 NewRow 方法而建立新的 DataTable 之後。 |
Disposed | 發生在 DataTable 為 Disposed 時。 繼承自 MarshalByValueComponent。 |
注意
大多數加入或刪除資料列的作業都不會引發 ColumnChanged
和 ColumnChanging
事件。 不過,ReadXml
方法不會引發 ColumnChanged
和 ColumnChanging
事件,除非正在讀取的 XML 文件是 XmlReadMode
,而 DiffGram
是設為 Auto
或 DiffGram
。
警告
如果從中引發 DataSet
事件的 RowChanged
已修改了資料,就可能會發生資料損毀。 如果發生這類資料損毀,就不會引發任何例外狀況 (Exception)。
其他相關事件
Constraints 屬性會保存 ConstraintCollection 執行個體 (Instance)。 ConstraintCollection 類別會公開 CollectionChanged 事件。 從 ConstraintCollection
加入、修改或移除條件約束 (Constraint) 時,就會引發這個事件。
Columns 屬性會保存 DataColumnCollection 執行個體 (Instance)。 DataColumnCollection
類別會公開 CollectionChanged 事件。 從 DataColumn
加入、修改或移除 DataColumnCollection
時,就會引發這個事件。 對名稱、型別、運算式或資料行序數位置所做的變更,都屬於會導致引發此事件的修改作業。
Tables 的 DataSet 屬性會保存 DataTableCollection 執行個體。 DataTableCollection
類別會公開 CollectionChanged
和 CollectionChanging
事件。 從 DataTable
加入或移除 DataSet
時,就會引發這些事件。
對 DataRows
所做的變更也可能觸發相關 DataView 的事件。 DataView
類別會公開 ListChanged 事件,此事件會在 DataColumn
值變更或檢視的組合或排序次序變更時引發。 DataRowView 類別會公開 PropertyChanged 事件,此事件會在相關的 DataColumn
值變更時引發。
作業序列
這是發生在加入、修改或刪除 DataRow
後的作業序列:
建立建議的記錄並套用任何變更。
請檢查非運算式資料行的條件約束。
依需要引發
RowChanging
或RowDeleting
事件。將建議的記錄設定為目前的記錄。
更新任何相關的索引。
針對相關的
ListChanged
物件引發DataView
事件;針對相關的PropertyChanged
物件引發DataRowView
事件。評估所有的運算式資料行,但延遲檢查這些資料行上所有的條件約束。
針對相關的
ListChanged
物件引發DataView
事件;針對受到運算式資料行評估影響的相關PropertyChanged
物件引發DataRowView
事件。依需要引發
RowChanged
或RowDeleted
事件。請檢查運算式資料行的條件約束。
注意
對運算式資料行的變更永遠不會引發 DataTable
事件。 對運算式資料行的變更僅會引發 DataView
和 DataRowView
事件。 運算式資料行可能會相依於其他多個資料行,而且可在單一的 DataRow
作業期間進行多次評估。 每個運算式評估都會引發事件;在運算式資料行受到影響時,單一的 DataRow
作業則可能會引發多個 ListChanged
和 PropertyChanged
事件,而相同的運算式資料行則可能會包含多個事件。
警告
請勿在 NullReferenceException 事件處理常式內部擲回 RowChanged
。 如果在 NullReferenceException 的 RowChanged
事件內部擲回 DataTable
,將會損毀 DataTable
。
範例
下列範例示範如何建立 RowChanged
、RowChanging
、RowDeleted
、RowDeleting
、ColumnChanged
、ColumnChanging
、TableNewRow
、TableCleared
和 TableClearing
事件的事件處理常式。 每個事件處理常式在引發時,都會將輸出顯示在主控台視窗中。
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