Explorar datos (Windows Forms para .NET)

La manera más fácil de navegar por los registros de un origen de datos es enlazar un componente BindingSource al origen de datos y, a continuación, enlazar controles a BindingSource. A continuación, puede usar el método de navegación integrado en el componente BindingSource, como MoveNext, MoveLast, MovePrevious y MoveFirst. Usar estos métodos ajustará las propiedades Position y Current del componente BindingSource apropiadamente. También puede encontrar un registro y establecerlo como el registro actual estableciendo la propiedad Position.

Para incrementar la posición del registro en un origen de datos

Establezca la propiedad Position del componente BindingSource para que los datos enlazados a la posición del registro vayan a la posición de registro requerida. En el ejemplo siguiente se muestra el uso del método MoveNext de BindingSource para incrementar la propiedad Position al seleccionar nextButton. BindingSource está asociado a la tabla Customers de un conjunto de datos Northwind.

private void nextButton_Click(object sender, System.EventArgs e)
{
    this.customersBindingSource.MoveNext();
}
Private Sub nextButton_Click(ByVal sender As Object,
    ByVal e As System.EventArgs) Handles nextButton.Click
    Me.customersBindingSource.MoveNext()
End Sub

Nota

Establecer la propiedad Position en un valor más allá del primer o último registro no produce un error, ya que Windows Forms no establecerá la posición en un valor fuera de los límites de la lista. Si es importante saber si se ha excedido el primer o último registro, incluya lógica para comprobar si se superará la cantidad de elementos de datos.

Para comprobar si ha superado el primer o último registro

Cree un controlador para el evento PositionChanged. En el controlador, puede probar si el valor de posición propuesto ha superado la cantidad real de elementos de datos.

En el ejemplo siguiente se muestra cómo probar si se ha alcanzado el último elemento de datos. En el ejemplo, si está en el último elemento, el botón Siguiente del formulario aparece deshabilitado.

void customersBindingSource_PositionChanged(object sender, EventArgs e)
{
    if (customersBindingSource.Position == customersBindingSource.Count - 1)
        nextButton.Enabled = false;
    else
        nextButton.Enabled = true;
}
Sub customersBindingSource_PositionChanged(ByVal sender As Object,
    ByVal e As EventArgs)

    If customersBindingSource.Position =
        customersBindingSource.Count - 1 Then
        nextButton.Enabled = False
    Else
        nextButton.Enabled = True
    End If
End Sub

Nota

Tenga en cuenta que, si cambia la lista que navega por el código, debe volver a habilitar el botón Siguiente para que los usuarios puedan examinar toda la longitud de la nueva lista. Además, tenga en cuenta que el evento PositionChanged anterior del componente BindingSource específico con el que está trabajando debe estar asociado a su método de control de eventos.

Para buscar un registro y establecerlo como elemento actual

Busque el registro que desea establecer como elemento actual. Use el método Find de BindingSource como se muestra en el ejemplo, si el origen de datos implementa IBindingList. Algunos ejemplos de orígenes de datos que implementan IBindingList son BindingList<T> y DataView.

void findButton_Click(object sender, EventArgs e)
{
    int foundIndex = customersBindingSource.Find("CustomerID", "ANTON");
    customersBindingSource.Position = foundIndex;
}
Sub findButton_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles findButton.Click
    Dim foundIndex As Integer = customersBindingSource.Find("CustomerID",
        "ANTON")
    customersBindingSource.Position = foundIndex
End Sub

Para garantizar que la fila seleccionada de una tabla secundaria conserva la posición correcta

Cuando trabaje con enlace de datos en Windows Forms, los datos se mostrarán en una vista primaria/secundaria o una vista maestra/detallada. Se trata de un escenario de enlace de datos donde los datos del mismo origen se muestran en dos controles. Al cambiar la selección en un control, los datos mostrados en el segundo control cambiarán. Por ejemplo, el primer control puede contener una lista de clientes y el segundo de una lista de pedidos relacionados con el cliente seleccionado en el primer control.

Cuando se muestran datos en una vista primaria/secundaria, quizás tenga que realizar algunos pasos adicionales para asegurarse de que la fila seleccionada actualmente en la tabla secundaria no se restablece a la primera fila de la tabla. Para ello, tendrá que almacenar en caché la posición de la tabla secundaria y restablecerla después de que cambie la tabla primaria. Normalmente, el restablecimiento de la tabla secundaria se produce la primera vez que cambia un campo en una fila de la tabla primaria.

Para almacenar en caché la posición de la tabla secundaria actual

  1. Declare una variable de entero para almacenar la posición de tabla secundaria y una variable booleana para almacenar en caché la posición de la tabla secundaria.

    private int cachedPosition = -1;
    private bool cacheChildPosition = true;
    
    Private cachedPosition As Integer = -1
    Private cacheChildPosition As Boolean = True
    
  2. Controle el evento ListChanged del CurrencyManager del enlace y busque un ListChangedType de Reset.

  3. Compruebe la posición actual del CurrencyManager. Si es mayor que la primera entrada de la lista (normalmente 0), guárdela en una variable.

    void relatedCM_ListChanged(object sender, ListChangedEventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked)
        {
            // If so, check to see if it is a reset situation, and the current
            // position is greater than zero.
            CurrencyManager relatedCM = sender as CurrencyManager;
            if (e.ListChangedType == ListChangedType.Reset && relatedCM.Position > 0)
    
                // If so, cache the position of the child table.
                cachedPosition = relatedCM.Position;
        }
    }
    
    Private Sub relatedCM_ListChanged(ByVal sender As Object,
        ByVal e As ListChangedEventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            ' If so, check to see if it is a reset situation, and the current
            ' position is greater than zero.
            Dim relatedCM As CurrencyManager = sender
            If e.ListChangedType = ListChangedType.Reset _
                AndAlso relatedCM.Position > 0 Then
    
                ' If so, cache the position of the child table.
                cachedPosition = relatedCM.Position
            End If
        End If
    
    End Sub
    
  4. Controle el evento CurrentChanged de la lista primaria para el administrador de moneda principal. En el controlador, establezca el valor booleano para indicar que no es un escenario de almacenamiento en caché. Si se produce CurrentChanged, el cambio en el elemento primario es un cambio de posición de lista y no un cambio de valor del elemento.

    void bindingSource1_CurrentChanged(object sender, EventArgs e)
    {
        // If the CurrentChanged event occurs, this is not a caching
        // situation.
        cacheChildPosition = false;
    }
    
    ' Handle the current changed event. This event occurs when
    ' the current item is changed, but not when a field of the current
    ' item is changed.
    Private Sub bindingSource1_CurrentChanged(ByVal sender As Object,
        ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
        ' If the CurrentChanged event occurs, this is not a caching 
        ' situation.
        cacheChildPosition = False
    
    End Sub
    

Para restablecer la posición de la tabla secundaria

  1. Controle el evento PositionChanged del elemento CurrencyManager del enlace de la tabla secundaria.

  2. Restablezca la posición de la tabla secundaria a la posición almacenada en caché que se guardó en el procedimiento anterior.

    void relatedCM_PositionChanged(object sender, EventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked)
        {
            CurrencyManager relatedCM = sender as CurrencyManager;
    
            // If so, check to see if the current position is
            // not equal to the cached position and the cached
            // position is not out of bounds.
            if (relatedCM.Position != cachedPosition && cachedPosition
                > 0 && cachedPosition < relatedCM.Count)
            {
                relatedCM.Position = cachedPosition;
                cachedPosition = -1;
            }
        }
    }
    
    Private Sub relatedCM_PositionChanged(ByVal sender As Object, ByVal e As EventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            Dim relatedCM As CurrencyManager = sender
    
            ' If so, check to see if the current position is 
            ' not equal to the cached position and the cached 
            ' position is not out of bounds.
            If relatedCM.Position <> cachedPosition AndAlso
                cachedPosition > 0 AndAlso cachedPosition <
                relatedCM.Count Then
                relatedCM.Position = cachedPosition
                cachedPosition = -1
            End If
        End If
    End Sub
    

Para probar el ejemplo de código, realice los pasos siguientes:

  1. Ejecute el ejemplo.

  2. Asegúrese de que la casilla Almacenar en caché y restablecer la posición está seleccionada.

  3. Seleccione el botón Borrar campo principal para producir un cambio en un campo de la tabla primaria. Observe que la fila seleccionada en la tabla secundaria no cambia.

  4. Cierre y vuelva a ejecutar el ejemplo. Debe volver a ejecutarlo porque el restablecimiento solo se produce en el primer cambio de la fila primaria.

  5. Desactive la casilla Almacenar en caché y restablecer posición.

  6. Seleccione el botón Borrar campo principal. Observe que la fila seleccionada en la tabla secundaria cambia a la primera fila.

Vea también