Behandeln von DataTable-Ereignissen

Das DataTable-Objekt stellt eine Reihe von Ereignissen bereit, die von einer Anwendung verarbeitet werden können. Eine Beschreibung dieser DataTable-Ereignisse finden Sie in der folgenden Tabelle:

Ereignis BESCHREIBUNG
Initialized Tritt ein, nachdem die EndInit-Methode einer DataTable aufgerufen wurde. Dieses Ereignis ist hauptsächlich zur Unterstützung von Szenarien zur Entwurfszeit gedacht.
ColumnChanged Tritt ein, nachdem ein Wert in einer DataColumn erfolgreich geändert wurde.
ColumnChanging Tritt ein, wenn ein Wert für eine DataColumn übermittelt wurde.
RowChanged Tritt ein, nachdem ein DataColumn-Wert oder der RowState einer DataRow in der DataTable erfolgreich geändert wurde.
RowChanging Tritt ein, wenn eine Änderung für einen DataColumn-Wert oder für den RowState einer DataRow in der DataTable übermittelt wurde.
RowDeleted Tritt ein, nachdem eine DataRow in der DataTable als Deleted gekennzeichnet wurde.
RowDeleting Tritt ein, bevor eine DataRow in der DataTable als Deleted gekennzeichnet wird.
TableCleared Tritt ein, nachdem ein Aufruf der Clear-Methode der DataTable jede DataRow erfolgreich gelöscht hat.
TableClearing Tritt ein, nachdem die Clear-Methode aufgerufen wurde, aber bevor der Clear-Vorgang beginnt.
TableNewRow Tritt ein, nachdem durch einen Aufruf der DataRow-Methode der NewRow eine neue DataTable erstellt wurde.
Disposed Tritt ein, wenn die DataTable in den Disposed-Status versetzt wurde. Wird von MarshalByValueComponent geerbt.

Hinweis

Die meisten Operationen, die Zeilen hinzufügen oder löschen, führen nicht zum Auslösen der Ereignisse ColumnChanged und ColumnChanging. Die ReadXml-Methode löst jedoch weiterhin das ColumnChanged-Ereignis und das ColumnChanging-Ereignis aus, bis XmlReadMode auf DiffGram oder auf Auto festgelegt ist, wenn das gelesene XML-Dokument ein DiffGram ist.

Warnung

Wenn Daten in einem DataSet geändert werden, über das das RowChanged-Ereignis ausgelöst wird, können Daten beschädigt werden. Bei einer solchen Datenbeschädigung wird keine Ausnahme ausgelöst.

Die Constraints-Eigenschaft enthält eine ConstraintCollection-Instanz. Die ConstraintCollection-Klasse macht ein CollectionChanged-Ereignis verfügbar. Dieses Ereignis wird ausgelöst, wenn eine Einschränkung hinzugefügt, geändert oder aus der ConstraintCollection entfernt wird.

Die Columns-Eigenschaft enthält eine DataColumnCollection-Instanz. Die DataColumnCollection-Klasse macht ein CollectionChanged-Ereignis verfügbar. Dieses Ereignis wird ausgelöst, wenn eine DataColumn hinzugefügt, geändert oder aus der DataColumnCollection entfernt wird. Zu den Änderungen, die das Ereignis auslösen, gehören Änderungen des Namens, des Typs, des Ausdrucks oder der Ordinalposition einer Spalte.

Die Tables-Eigenschaft eines DataSet enthält eine DataTableCollection-Instanz. Die DataTableCollection-Klasse macht sowohl ein CollectionChanged-Ereignis als auch ein CollectionChanging-Ereignis verfügbar. Diese Ereignisse werden ausgelöst, wenn eine DataTable hinzugefügt oder aus dem DataSet entfernt wird.

Änderungen an DataRows können auch Ereignisse für eine verknüpfte DataView auslösen. Die DataView-Klasse macht ein ListChanged-Ereignis verfügbar, das ausgelöst wird, wenn sich ein DataColumn-Wert ändert oder wenn sich die Zusammensetzung oder Sortierreihenfolge der Ansicht ändert. Die DataRowView-Klasse macht ein PropertyChanged-Ereignis verfügbar, das ausgelöst wird, wenn sich ein verknüpfter DataColumn-Wert ändert.

Abfolge der Vorgänge

Beim Hinzufügen, Ändern oder Löschen einer DataRow laufen die Vorgänge in der folgenden Reihenfolge ab:

  1. Der vorgeschlagene Datensatz wird erstellt, und alle Änderungen werden übernommen.

  2. Die Einschränkungen für Nicht-Ausdruck-Spalten werden überprüft.

  3. Das RowChanging-Ereignis oder das RowDeleting-Ereignis wird ausgelöst.

  4. Der vorgeschlagene Datensatz wird als aktueller Datensatz festgelegt.

  5. Alle zugeordneten Indizes werden aktualisiert.

  6. Die ListChanged-Ereignisse für zugeordnete DataView-Objekte und die PropertyChanged-Ereignisse für zugeordnete DataRowView-Objekte werden ausgelöst.

  7. Alle Ausdrucksspalten werden ausgewertet, wobei aber die Überprüfung der Einschränkungen für diese Spalten verzögert wird.

  8. Die ListChanged-Ereignisse für die zugeordneten DataView-Objekte und die PropertyChanged-Ereignisse für die zugeordneten DataRowView-Objekte, auf die sich die Auswertung der Ausdrucksspalten auswirkt, werden ausgelöst.

  9. Das RowChanged-Ereignis oder das RowDeleted-Ereignis wird ausgelöst.

  10. Die Einschränkungen für Ausdrucksspalten werden überprüft.

Hinweis

Änderungen an Ausdrucksspalten führen nie dazu, dass DataTable-Ereignisse ausgelöst werden. Änderungen an Ausdrucksspalten lösen lediglich die Ereignisse DataView und DataRowView aus. Ausdrucksspalten können Abhängigkeiten von mehreren anderen Spalten besitzen und während eines einzelnen DataRow-Vorgangs mehrmals ausgewertet werden. Jede Ausdrucksauswertung löst Ereignisse aus, und ein einzelner DataRow-Vorgang kann mehrere ListChanged- und PropertyChanged-Ereignisse auslösen, sofern Ausdrucksspalten betroffen sind. Dabei ist es auch möglich, dass für ein und dieselbe Ausdrucksspalte mehrere Ereignisse ausgelöst werden.

Warnung

Lösen Sie keine NullReferenceException im RowChanged-Ereignishandler aus. Wenn eine NullReferenceException im RowChanged-Ereignis einer DataTable ausgelöst wird, führt dies zur Beschädigung der DataTable.

Beispiel

Das folgende Beispiel zeigt, wie Ereignishandler für die Ereignisse RowChanged, RowChanging, RowDeleted, RowDeleting, ColumnChanged, ColumnChanging, TableNewRow, TableCleared und TableClearing erstellt werden können. Jeder Ereignishandler zeigt die Ausgabe beim Auslösen der Ereignisse im Konsolenfenster an.

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

Siehe auch