DataTable イベントの処理

DataTable オブジェクトは、アプリケーションが処理できる一連のイベントを提供します。 DataTable のイベントを次の表に示します。

event 説明
Initialized EndInitDataTable メソッドが呼び出された後に発生します。 このイベントは、主にデザイン時のシナリオをサポートすることを目的としています。
ColumnChanged DataColumn で値が正常に変更された後に発生します。
ColumnChanging DataColumn に対して値が送信されたときに発生します。
RowChanged DataColumn 値または RowStateDataRowDataTable が正常に変更された後で発生します。
RowChanging DataColumn 値または RowStateDataRowDataTable に対して変更が送信されたときに発生します。
RowDeleted DataRowDataTableDeleted としてマークされた後に発生します。
RowDeleting DataRowDataTableDeleted としてマークされる前に発生します。
TableCleared ClearDataTable メソッドがすべての DataRow を正常にクリアした後で発生します。
TableClearing Clear メソッドが呼び出された後、Clear 操作が開始される前に発生します。
TableNewRow DataRowNewRow メソッドの呼び出しにより、新しい DataTable が作成された後で発生します。
Disposed DataTable が破棄 (Disposed) されたときに発生します。 このプロパティは、MarshalByValueComponent から継承されています。

Note

行の追加または削除を行う操作の多くは、ColumnChanged イベントも ColumnChanging イベントも生成しません。 ただし、ReadXml メソッドでは、ColumnChangedColumnChanging または XmlReadMode (読み込む XML ドキュメントが DiffGram の場合) に設定されていない限り、Auto イベントおよび DiffGram イベントが生成されます。

警告

DataSet イベントの生成元の RowChanged でデータが変更されると、データが破損する可能性があります。 このようなデータの破損が起きた場合、例外は発生しません。

Constraints プロパティは ConstraintCollection インスタンスを保持します。 ConstraintCollection クラスは、CollectionChanged イベントを公開します。 このイベントは、ConstraintCollection に対して制約の追加、変更、または削除が実行されたときに発生します。

Columns プロパティは DataColumnCollection インスタンスを保持します。 DataColumnCollection クラスは、CollectionChanged イベントを公開します。 このイベントは、DataColumn が追加、変更、または DataColumnCollection から削除されたときに発生します。 イベントの発生を伴う変更には、名前の変更、型の変更、式の変更、列の序数位置の変更などがあります。

TablesDataSet プロパティは DataTableCollection インスタンスを保持します。 DataTableCollection クラスは、CollectionChanged イベントと CollectionChanging イベントの両方を公開します。 これらのイベントは、DataTable に対して、DataSet の追加、変更、または削除が実行されたときに発生します。

DataRows への変更によって、関連する DataView のイベントがトリガーされる場合もあります。 DataView クラスは、ListChanged 値が変更されたとき、または、ビューの構成や並べ替え順が変更されたときに発生する DataColumn イベントを公開します。 DataRowView クラスは、関連する PropertyChanged 値が変更されたときに発生する DataColumn イベントを公開します。

操作の順序

DataRow が追加、変更、または削除されたときに発生する操作の順序について説明します。

  1. 提示されたレコードを作成し、変更を適用します。

  2. 式以外の列の制約をチェックします。

  3. 適宜 RowChanging イベントまたは RowDeleting イベントを発生させます。

  4. 提示されたレコードを現在のレコードとして設定します。

  5. 関連するインデックスをすべて更新します。

  6. 関連する ListChanged オブジェクトの DataView イベントおよび関連する PropertyChanged オブジェクトの DataRowView イベントを発生させます。

  7. すべての式列を評価します。ただし、これらの列に対する制約のチェックは、この段階では行われません。

  8. 式列の評価によって影響を受ける、関連する ListChanged オブジェクトの DataView イベントおよび関連する PropertyChanged オブジェクトの DataRowView イベントを発生させます。

  9. 適宜 RowChanged イベントまたは RowDeleted イベントを発生させます。

  10. 式列の制約をチェックします。

Note

式列に対する変更で DataTable のイベントが発生することはありません。 式列に対する変更で発生するのは、DataViewDataRowView のイベントだけです。 式列には他の複数の列に対する依存関係が存在することもあるため、1 回の DataRow 操作で複数回、評価される場合もあります。 イベントは式が評価されるたびに発生するため、式列が変更された場合、1 回の DataRow 操作で複数の ListChanged イベントおよび PropertyChanged イベントが発生し、同じ式列に対して複数のイベントが発生する場合もあります。

警告

NullReferenceExceptionRowChanged イベント ハンドラー内でスローしないでください。 NullReferenceExceptionRowChangedDataTable イベント内でスローされると、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

関連項目