Gestione di eventi DataTable

Nell'oggetto DataTable sono disponibili diversi eventi che possono essere elaborati da un'applicazione. Nella tabella seguente vengono descritti gli eventi di DataTable.

Event Descrizione
Initialized Viene generato dopo la chiamata al metodo EndInit di DataTable. Questo evento è progettato principalmente per supportare gli scenari in fase di progettazione.
ColumnChanged Viene generato dopo la modifica di un valore in DataColumn.
ColumnChanging Viene generato quando un valore è stato inviato per una DataColumn.
RowChanged Viene generato dopo la modifica di un valore DataColumn o di RowState di DataRow nella DataTable.
RowChanging Viene generato quando è stata inviata una modifica per un valore DataColumn o per RowState di DataRow nella DataTable.
RowDeleted Viene generato dopo che una DataRow nella DataTable è stata contrassegnata come Deleted.
RowDeleting Viene generato prima che una DataRow nella DataTable venga contrassegnata come Deleted.
TableCleared Viene generato dopo che una chiamata al metodo Clear di DataTable ha cancellato correttamente ogni DataRow.
TableClearing Viene generato dopo una chiamata al metodo Clear ma prima dell'inizio dell'operazione Clear.
TableNewRow Viene generato dopo la creazione di una nuova DataRow tramite una chiamata al metodo NewRow della DataTable.
Disposed Viene generato quando DataTable è Disposed. Ereditato da MarshalByValueComponent.

Nota

La maggior parte delle operazioni che aggiungono o eliminano righe non generano gli eventi ColumnChanged e ColumnChanging. Tuttavia, il metodo ReadXml genera gli eventi ColumnChanged e ColumnChanging, a meno che XmlReadMode non sia impostato su DiffGram o su Auto quando il documento XML da leggere è un DiffGram.

Avviso

I dati possono venire danneggiati se vengono modificati in un oggetto DataSet da cui viene generato l'evento RowChanged. In caso di danneggiamento dei dati, non viene generata alcuna eccezione.

La proprietà Constraints contiene un'istanza di ConstraintCollection. La classe ConstraintCollection espone un evento CollectionChanged. Questo evento viene attivato quando un vincolo viene aggiunto, modificato o rimosso da ConstraintCollection.

La proprietà Columns contiene un'istanza di DataColumnCollection. La classe DataColumnCollection espone un evento CollectionChanged. Questo evento viene attivato quando una DataColumn viene aggiunta, modificata o rimossa da DataColumnCollection. Le modifiche che causano l'attivazione dell'evento includono le modifiche al nome, tipo, espressione o posizione ordinale di una colonna.

La proprietà Tables di DataSet contiene un'istanza di DataTableCollection. La classe DataTableCollection espone sia un evento CollectionChanged sia un evento CollectionChanging. Questi eventi vengono attivati quando una DataTable viene aggiunta, modificata o rimossa dal DataSet.

Le modifiche a DataRows possono attivare anche eventi per un oggetto DataView associato. La classe DataView espone un evento ListChanged che viene attivato quando viene modificato un valore DataColumn oppure la composizione o l'ordine della visualizzazione. La classe DataRowView espone un evento PropertyChanged che viene attivato quando viene modificato valore DataColumn associato.

sequenza delle operazioni

Di seguito è riportata la sequenza delle operazioni che si verificano quando una DataRow viene aggiunta, modificata o eliminata:

  1. Creare il record proposto e applicare eventuali modifiche.

  2. Verificare i vincoli per le colonne non espressioni.

  3. Generare gli eventi RowChanging o RowDeleting come applicabile.

  4. Impostare il record proposto come record corrente.

  5. Aggiornare gli eventuali indici associati.

  6. Generare gli eventi ListChanged per gli oggetti DataView associati e gli eventi PropertyChanged per gli oggetti DataRowView associati.

  7. Valutare tutte le colonne espressioni, ma rimandare la verifica della presenza di vincoli su queste colonne.

  8. Generare gli eventi ListChanged per gli oggetti DataView associati e gli eventi PropertyChanged per gli oggetti DataRowView associati interessati dalle valutazioni delle colonne espressioni.

  9. Generare gli eventi RowChanged o RowDeleted come applicabile.

  10. Verificare i vincoli per le colonne espressioni.

Nota

Le modifiche alle colonne espressioni non generano mai eventi DataTable, ma generano solo eventi DataView e DataRowView, Le colonne espressioni possono avere dipendenze su molte altre colonne e possono essere valutate più volte durante una singola operazione DataRow. Ogni valutazione di espressione genera eventi e una singola operazione DataRow può generare più eventi ListChanged e PropertyChanged quando sono interessate colonne espressioni, magari con più eventi per la stessa colonna espressioni.

Avviso

Non generare un'eccezione NullReferenceException all'interno del gestore eventi RowChanged. Se viene generata un'eccezione NullReferenceException all'interno dell'evento RowChanged di un oggetto DataTable, quest'ultimo sarà danneggiato.

Esempio

Nell'esempio seguente viene illustrato come creare gestori per gli eventi RowChanged, RowChanging, RowDeleted, RowDeleting, ColumnChanged, ColumnChanging, TableNewRow, TableCleared e TableClearing. Ogni gestore evento visualizza l'output nella finestra della console quando viene attivato.

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

Vedi anche