浏览数据

在数据源中导航记录的最简单方法是将 BindingSource 组件绑定到数据源,然后将控件绑定到 BindingSource。 然后,可以使用 BindingSource的内置导航方法,例如 MoveNextMoveLastMovePreviousMoveFirst。 使用这些方法可以适当地调整 PositionCurrentBindingSource 属性。 还可以通过设置 Position 属性来查找记录并将其设置为当前记录。

递增数据源中的记录位置

将绑定数据的 PositionBindingSource 属性设置为可转到必需记录位置的记录位置。 以下示例演示如何在选择 MoveNext时,使用 BindingSourcePosition 方法,递增 nextButton 属性。 BindingSource 与数据集 CustomersNorthwind 表相关联。

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

注释

Position 属性设置为超出第一条或最后一条记录的值不会导致错误,因为 Windows 窗体不会将位置设置为列表边界之外的值。 如果必须知道是否已超过第一条或最后一条记录,请包含用于测试是否会超过数据元素计数的逻辑。

检查是否已超过第一条或最后一条记录

PositionChanged 事件创建事件处理程序。 在处理程序中,可以测试建议的位置值是否已超过实际数据元素计数。

以下示例演示如何测试是否已到达最后一个数据元素。 在该示例中,如果位于最后一个元素,则窗体上的“下一个”按钮处于禁用状态

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

注释

请注意,如果在代码中更改导航的列表,则应重新启用“下一个”按钮,以便用户可以浏览整个新列表。 此外,请注意,你正在使用的特定 PositionChanged 的上述 BindingSource 事件需要与其事件处理方法关联。

查找记录并将其设置为当前项

找到要设置为当前项的记录。 如果数据源实现 Find,请使用 BindingSourceIBindingList 方法,如示例中所示。 实现 IBindingList 的数据源的一些示例是 BindingList<T>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

确保子表中的选定行保持在正确的位置

当在 Windows 窗体中使用数据绑定时,将显示父/子视图或母版/详细视图中的数据。 它是一种数据绑定情境,其中来自同一源的数据被显示于两个控件中。 更改一个控件中的选定内容会导致第二个控件中显示的数据发生更改。 例如,第一个控件可能包含客户列表,第二个控件包含与第一个控件中所选客户相关的订单列表。

在父/子视图中显示数据时,可能需要执行额外的步骤,以确保子表中当前选定的行不会重置为表的第一行。 为此,你必须缓存子表位置,并在父表更改后重置它。 通常,子表重置发生在父表行中的字段首次更改时。

缓存当前子表位置

  1. 声明一个整数变量来存储子表位置,以及用于存储是否缓存子表位置的布尔变量。

    private int cachedPosition = -1;
    private bool cacheChildPosition = true;
    
    Private cachedPosition As Integer = -1
    Private cacheChildPosition As Boolean = True
    
  2. 为绑定的 ListChanged 处理 CurrencyManager 事件并检查 ListChangedTypeReset

  3. 检查 CurrencyManager 的当前位置。 如果它大于列表中的第一个条目(通常为 0),请将其保存到变量。

    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. 为父货币管理器处理父列表的 CurrentChanged 事件。 在处理程序中,设置布尔值以指示它不是缓存方案。 如果发生 CurrentChanged,则对父项的更改是列表位置的更改,而不是项值更改。

    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
    

重置子表位置

  1. 为子表绑定的 PositionChanged 处理 CurrencyManager 事件。

  2. 将子表位置重置为在上一过程中保存的缓存位置。

    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
    

若要测试代码示例,请执行以下步骤:

  1. 运行示例。

  2. 请确保“缓存并重置位置”复选框处于选中状态

  3. 选择 “清除父字段” 按钮以更改父表中的一个字段。 请注意,子表中的选定行不会更改。

  4. 关闭并重新运行示例。 需要再次运行它,因为重置行为仅在父行的第一次更改上发生。

  5. 清除 缓存并重置位置 的复选框。

  6. 选择“清除父字段”按钮。 请注意,子表中的选定行将更改为第一行。

另请参阅