Controlar eventos de DataTable

El objeto DataTable proporciona una serie de eventos que una aplicación puede procesar. En la siguiente tabla se describen los eventos de DataTable.

Evento Descripción
Initialized Se produce después de haber llamado al método EndInit de un objeto DataTable. Este evento está concebido principalmente para admitir escenarios en tiempo de diseño.
ColumnChanged Se produce después de cambiar correctamente un valor en un objeto DataColumn.
ColumnChanging Se produce cuando se ha enviado un valor para un objeto DataColumn.
RowChanged Se produce cuando se ha cambiado correctamente un valor de DataColumn o la propiedad RowState de un objeto DataRow en el objeto DataTable.
RowChanging Se produce cuando se ha enviado un cambio para un valor DataColumn o la propiedad RowState de un objeto DataRow en el objeto DataTable.
RowDeleted Se produce después de marcar un objeto DataRow de un objeto DataTable como Deleted.
RowDeleting Se produce antes de marcar un objeto DataRow de un objeto DataTable como Deleted.
TableCleared Se produce después de que una llamada al método Clear del objeto DataTable haya borrado correctamente todos los objetos DataRow.
TableClearing Se produce después de haber llamado al método Clear pero antes de que se inicie la operación Clear.
TableNewRow Se produce después de crear un nuevo objeto DataRow mediante una llamada al método NewRow del objeto DataTable.
Disposed Se produce cuando el objeto DataTable se establece en Disposed. Se hereda de MarshalByValueComponent.

Nota

La mayoría de las operaciones que agregan o eliminan filas no generan eventos ColumnChanged ni ColumnChanging. Sin embargo, el método ReadXml sí genera eventos ColumnChanged y ColumnChanging, a menos que XmlReadMode se establezca en DiffGram o se establezca en Auto cuando el documento XML que se lee es DiffGram.

Advertencia

Es posible que los datos resulten dañados si se modifican en un DataSet desde el que se genera el evento RowChanged. No se producirá ninguna excepción si se produce este tipo de daño en los datos.

La propiedad Constraints contiene una instancia de ConstraintCollection. La clase ConstraintCollection expone un evento CollectionChanged. Este evento se activa cuando se agrega, modifica o quita una restricción de ConstraintCollection.

La propiedad Columns contiene una instancia de DataColumnCollection. La clase DataColumnCollection expone un evento CollectionChanged. Este evento se activa cuando se agrega, modifica o quita un objeto DataColumn de DataColumnCollection. Entre las modificaciones que generan el inicio del evento se encuentran los cambios en el nombre, el tipo, la expresión o la posición ordinal de una columna.

La propiedad Tables de un objeto DataSet incluye una instancia de DataTableCollection. La clase DataTableCollection expone los eventos CollectionChanged y CollectionChanging. Estos eventos se activan cuando se agrega o se quita un objeto DataTable del DataSet.

Los cambios en DataRows también pueden activar eventos de un objeto DataView asociado. La clase DataView expone un evento ListChanged que se activa cuando cambia un valor de DataColumn o cuando cambian la composición o el criterio de ordenación de la vista. La clase DataRowView expone un evento PropertyChanged que se activa cuando cambia un valor de DataColumn asociado.

Secuencia de operaciones

A continuación se indica la secuencia de las operaciones que tienen lugar cuando se agrega, modifica o elimina un objeto DataRow.

  1. Se crea el registro propuesto y se aplican los cambios.

  2. Se comprueban las restricciones en columnas que no son de expresión.

  3. Se generan los eventos RowChanging o RowDeleting, según corresponda.

  4. El registro propuesto se establece en el registro actual.

  5. Se actualizan los índices asociados.

  6. Se generan los eventos ListChanged de los objetos DataView asociados y los eventos PropertyChanged de los objetos DataRowView asociados.

  7. Se evalúan todas las columnas de expresión, pero se retrasa la comprobación de las restricciones de estas columnas.

  8. Se generan los eventos ListChanged de los objetos DataView asociados y los eventos PropertyChanged de los objetos DataRowView asociados a los que afecten las evaluaciones de la columna de expresión.

  9. Se generan los eventos RowChanged o RowDeleted, según corresponda.

  10. Se comprueban las restricciones en las columnas de expresión.

Nota

Los cambios en las columnas de expresión nunca generan eventos DataTable. Los cambios en las columnas de expresión solo generan eventos DataView y DataRowView. Las columnas de expresión pueden tener dependencias en otras columnas y se pueden evaluar varias veces durante una única operación de DataRow. Cada evaluación de expresión genera eventos, y una sola operación de DataRow puede generar varios eventos ListChanged y PropertyChanged cuando se ven afectadas columnas de expresión, que posiblemente incluyen varios eventos para la misma columna de expresión.

Advertencia

No inicie una excepción NullReferenceException dentro del controlador de eventos RowChanged. Si se inicia una excepción NullReferenceException dentro del evento RowChanged de un objeto DataTable, el objeto DataTable resultará dañado.

Ejemplo

En el ejemplo siguiente se muestra cómo crear controladores de eventos para los eventos RowChanged, RowChanging, RowDeleted, RowDeleting, ColumnChanged, ColumnChanging, TableNewRow, TableCleared y TableClearing. Cada controlador de eventos muestra resultado en la ventana de la consola cuando se activa.

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

Consulte también