Navigieren durch Daten (Windows Forms .NET)

Die einfachste Möglichkeit, durch die Datensätze in einer Datenquelle zu navigieren, besteht darin, eine BindingSource-Komponente an die Datenquelle und die Steuerelemente an das BindingSource-Objekt zu binden. Anschließend können Sie die integrierte Navigationsmethode von BindingSource verwenden, z. B. MoveNext, MoveLast, MovePrevious und MoveFirst. Durch die Verwendung dieser Methoden werden die Eigenschaften Position und Current von BindingSource entsprechend angepasst. Sie können einen Datensatz auch suchen und als aktuellen Datensatz festlegen, indem Sie die Position-Eigenschaft festlegen.

So erhöhen Sie die Datensatzposition in einer Datenquelle

Legen Sie die Position-Eigenschaft von BindingSource für die gebundenen Daten auf die Datensatzposition fest, um zur erforderlichen Datensatzposition zu wechseln. Im folgenden Beispiel wird veranschaulicht, wie die Methode MoveNext von BindingSource verwendet wird, um die Position-Eigenschaft zu erhöhen, wenn Sie die nextButton auswählen. Das BindingSource-Objekt ist der Customers-Tabelle eines Datasets Northwind zugeordnet.

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

Hinweis

Das Festlegen der Eigenschaft Position auf einen Wert außerhalb des ersten oder letzten Datensatzes führt nicht zu einem Fehler, da Windows Forms die Position nicht auf einen Wert außerhalb der Grenzen der Liste festlegen würde. Wenn es wichtig ist zu wissen, ob der erste oder letzte Datensatz unter-/überschritten wurde, schließen Sie Logik ein, um zu testen, ob die Anzahl der Datenelemente überschritten wird.

So überprüfen Sie, ob Sie den ersten oder letzten Datensatz überschritten haben

Erstellen Sie einen Ereignishandler für das PositionChanged-Ereignis. Im Handler können Sie testen, ob der vorgeschlagene Positionswert die tatsächliche Datenelementanzahl überschreitet.

Im folgenden Beispiel wird veranschaulicht, wie Sie testen können, ob Sie das letzte Datenelement erreicht haben. Wenn Sie sich im letzten Element befinden, wird die Schaltfläche Weiter im Formular deaktiviert.

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

Hinweis

Beachten Sie im Falle einer Änderung der Liste, durch die Sie im Code navigieren, dass Sie die Schaltfläche Weiter wieder aktivieren sollten, sodass die Benutzer die gesamte Länge der neuen Liste durchsuchen können. Beachten Sie außerdem, dass das obige PositionChanged-Ereignis für das spezifische BindingSource-Objekt, mit dem Sie arbeiten, der entsprechenden Ereignisbehandlungsmethode zugeordnet werden muss.

So suchen Sie einen Datensatz und legen ihn als aktuelles Element fest

Suchen Sie den Datensatz, den Sie als aktuelles Element festlegen möchten. Verwenden Sie die Find-Methode der BindingSource wie im Beispiel gezeigt, wenn ihre Datenquelle IBindingList implementiert. Einige Beispiele für Datenquellen, die IBindingList implementieren, sind BindingList<T> und 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

So stellen Sie sicher, dass die ausgewählte Zeile in einer untergeordneten Tabelle an der richtigen Position bleibt

Wenn Sie mit der Datenbindung in Windows Forms arbeiten, zeigen Sie Daten in einer übergeordneten/untergeordneten oder Master-/Detailansicht an. Dabei handelt es sich um ein Datenbindungsszenario, bei dem Daten aus der gleichen Quelle in zwei Steuerelementen angezeigt werden. Wird die Auswahl in einem Steuerelement geändert, ändern sich die Daten, die im zweiten Steuerelement angezeigt werden. So enthält das erste Steuerelement möglicherweise eine Kundenliste, und im zweiten Steuerelement wird eine Liste der Bestellungen angezeigt, die der im ersten Steuerelement ausgewählte Kunde getätigt hat.

Wenn Sie Daten in einer übergeordneten/untergeordneten Ansicht anzeigen, müssen Sie möglicherweise zusätzliche Schritte ausführen, um sicherzustellen, dass die aktuell ausgewählte Zeile in der untergeordneten Tabelle nicht auf die erste Zeile der Tabelle zurückgesetzt wird. Hierfür müssen Sie die Position in der untergeordneten Tabelle zwischenspeichern und zurücksetzen, nachdem die übergeordnete Tabelle geändert wurde. Normalerweise erfolgt das Zurücksetzen der untergeordneten Tabelle zum ersten Mal, wenn ein Feld in einer Zeile der übergeordneten Tabelle geändert wird.

So speichern Sie die aktuelle Position der untergeordneten Tabelle zwischen

  1. Deklarieren Sie eine ganzzahlige Variable zum Speichern der Position in der untergeordneten Tabelle und eine boolesche Variable, um zu speichern, ob die Position der untergeordneten Tabelle zwischengespeichert werden soll.

    private int cachedPosition = -1;
    private bool cacheChildPosition = true;
    
    Private cachedPosition As Integer = -1
    Private cacheChildPosition As Boolean = True
    
  2. Behandeln Sie das ListChanged-Ereignis für den CurrencyManager der Bindung, und prüfen Sie auf einen ListChangedType von Reset.

  3. Überprüfen Sie die aktuelle Position von CurrencyManager. Ist diese größer als der erste Eintrag in der Liste (normalerweise 0), speichern Sie sie in einer Variablen.

    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. Behandeln Sie das CurrentChanged-Ereignis für den übergeordneten Währungs-Manager der übergeordneten Liste. Legen Sie im Handler den booleschen Wert fest, um anzugeben, dass es sich nicht um ein Zwischenspeicherungsszenario handelt. Wenn CurrentChanged auftritt, handelt es sich bei der Änderung an der übergeordneten Liste um eine Positionsänderung und nicht um eine Änderung des Elementwerts.

    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
    

So setzen Sie die Position der untergeordneten Tabelle zurück

  1. Behandeln Sie das PositionChanged-Ereignis für den CurrencyManager der Bindung der untergeordneten Tabelle.

  2. Setzen Sie die Position in der untergeordneten Tabelle auf die zwischengespeicherte Position zurück, die mit der vorherigen Prozedur gespeichert wurde.

    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
    

Führen Sie die folgenden Schritte aus, um das Codebeispiel zu testen:

  1. Führen Sie das Beispiel aus.

  2. Vergewissern Sie sich, dass das Kontrollkästchen Position zwischenspeichern und zurücksetzen aktiviert ist.

  3. Wählen Sie die Schaltfläche Übergeordnetes Feld löschen aus, um eine Änderung an einem Feld der übergeordneten Tabelle zu veranlassen. Beachten Sie, dass sich die ausgewählte Zeile in der untergeordneten Tabelle nicht ändert.

  4. Schließen Sie das Beispiel, und führen Sie es erneut aus. Sie müssen es erneut ausführen, da die Rücksetzung erst nach der ersten Änderung in der übergeordneten Zeile stattfindet.

  5. Deaktivieren Sie das Kontrollkästchen Position zwischenspeichern und zurücksetzen.

  6. Wählen Sie die Schaltfläche Übergeordnetes Feld löschen aus. Beachten Sie, dass sich die ausgewählte Zeile in der untergeordneten Tabelle nun auf die erste Zeile ändert.

Weitere Informationen