DataRepeater 控件中的虚拟模式 (Visual Studio)

如果要在 DataRepeater 控件中显示大量表格数据,可通过将 VirtualMode 属性设置为 True 并显式管理该控件与其数据源的交互来提高性能。 DataRepeater 控件提供若干事件,您可以处理这些事件来与数据源交互并根据需要在运行时显示数据。

虚拟模式的工作原理

DataRepeater 控件最常见的用法是在设计时将 ItemTemplate 的子控件绑定到数据源并使 BindingSource 可以根据需要来回传递数据。 使用虚拟模式时,控件不绑定到数据源,数据在运行时传入或传出底层数据源。

VirtualMode 属性设置为 True 时,您可以通过从**“工具箱”添加控件来创建用户界面,而不从“数据源”**窗口添加绑定控件。

事件的引发是基于控件的,并且您必须添加代码来处理数据的显示。 当某个新的 DataRepeaterItem 滚动到视图中时,将为每个控件引发一次 ItemValueNeeded 事件,因此您必须在 ItemValueNeeded 事件处理程序中为每个控件提供值。

如果用户更改了某个控件中的数据,将引发 ItemValuePushed 事件,因此您必须验证数据并将它保存到数据源中。

如果用户添加新项,将引发 NewItemNeeded 事件。 使用此事件的处理程序在数据源中创建新记录。 若要防止意外更改,还必须监视每个控件的 KeyDown 事件,并在用户按 Esc 键时调用 CancelEdit

如果数据源发生更改,则可通过调用 BeginResetTemplateItem 和 EndResetTemplateItem 方法来刷新 DataRepeater 控件。 必须按顺序调用这两种方法。

最后,您还必须实现 ItemsRemoved 事件的事件处理程序,该事件在删除项时发生;还可以选择实现 UserDeletingItemsUserDeletedItems 事件的事件处理程序,这两个事件在用户通过按 Delete 键删除项时发生。

实现虚拟模式

下面是实现虚拟模式所需的步骤。

实现虚拟模式

  1. 从**“工具箱”“Visual Basic PowerPacks”**选项卡中将 DataRepeater 控件拖到窗体或容器控件中。 将 VirtualMode 属性设置为 True。

  2. 从**“工具箱”**中将控件拖到 DataRepeater 控件的项模板区域(上半部分区域)。 您需要为数据源中要显示的每个字段分别添加一个控件。

  3. ItemValueNeeded 事件实现一个处理程序以便为每个控件提供值。 此事件在某个新的 DataRepeaterItem 滚动到视图中时引发。 代码与下面的示例类似,此示例针对一个名为 Employees 的数据源。

    Private Sub DataRepeater1_ItemValueNeeded(
        ByVal sender As Object, 
        ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemValueEventArgs
      ) Handles DataRepeater1.ItemValueNeeded
        If e.ItemIndex < Employees.Count Then
            Select Case e.Control.Name
                Case "txtFirstName"
                    e.Value = Employees.Item(e.ItemIndex + 1).firstName
                Case "txtLastName"
                    e.Value = Employees.Item(e.ItemIndex + 1).lastName
            End Select
        End If
    End Sub
    
    private void dataRepeater1_ItemValueNeeded(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemValueEventArgs e)
    {
        if (e.ItemIndex < Employees.Count)
        {
            switch (e.Control.Name)
            {
                case "txtFirstName":
                    e.Value = Employees[e.ItemIndex + 1].firstName;
                    break;
                case "txtLastName":
                    e.Value = Employees[e.ItemIndex + 1].lastName;
                    break;
            }
        }
    }
    
  4. ItemValuePushed 事件实现一个处理程序来存储数据。 此事件在用户将更改提交到 DataRepeaterItem 的子控件时引发。 代码与下面的示例类似,此示例针对一个名为 Employees 的数据源。

    Private Sub DataRepeater1_ItemValuePushed(
        ByVal sender As Object, 
        ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemValueEventArgs
      ) Handles DataRepeater1.ItemValuePushed
    
        Dim emp As Employee = Employees.Item(e.ItemIndex)
        Select Case e.Control.Name
            Case "txtFirstName"
                emp.firstName = e.Control.Text
            Case "txtLastName"
                emp.lastName = e.Control.Text
            Case Else
                MsgBox("Error during ItemValuePushed unexpected control: " & 
                    e.Control.Name)
        End Select
    End Sub
    
    private void dataRepeater1_ItemValuePushed(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemValueEventArgs e)
    {
        Employee emp = Employees[e.ItemIndex];
        switch (e.Control.Name)
        {
            case "txtFirstName":
                emp.firstName = e.Control.Text;
                break;
            case "txtLastName":
                emp.lastName = e.Control.Text;
                break;
            default:
                MessageBox.Show("Error during ItemValuePushed unexpected control: " + e.Control.Name);
                break;
        }
    }
    
  5. 分别为每个子控件的 KeyDown 事件实现一个处理程序并监视 Esc 键。 调用 CancelEdit 方法来防止引发 ItemValuePushed 事件。 代码与下面的示例类似。

    Private Sub Child_KeyDown(
        ByVal sender As Object, 
        ByVal e As System.Windows.Forms.KeyEventArgs
      ) Handles txtFirstName.KeyDown, txtLastName.KeyDown
    
        If e.KeyCode = Keys.Escape Then
            Datarepeater1.CancelEdit()
        End If
    End Sub
    
    private void child_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Escape)
        {
            this.dataRepeater1.CancelEdit();
        }
    }
    
  6. NewItemNeeded 事件实现一个处理程序。 此事件在用户向 DataRepeater 控件中添加新项时引发。 代码与下面的示例类似,此示例针对一个名为 Employees 的数据源。

    Private Sub DataRepeater1_NewItemNeeded(
      ) Handles DataRepeater1.NewItemNeeded
    
        Dim newEmployee As New Employee
        Employees.Add(newEmployee)
        blnNewItemNeedEventFired = True
    End Sub
    
    private void dataRepeater1_NewItemNeeded(object sender, System.EventArgs e)
    {
        Employee newEmployee = new Employee();
        Employees.Add(newEmployee);
        blnNewItemNeedEventFired = true;
    }
    
  7. ItemsRemoved 事件实现一个处理程序。 此事件在用户删除现有项时发生。 代码与下面的示例类似,此示例针对一个名为 Employees 的数据源。

    Private Sub DataRepeater1_ItemsRemoved(
        ByVal sender As Object, 
        ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterAddRemoveItemsEventArgs
      ) Handles DataRepeater1.ItemsRemoved
    
        Employees.RemoveAt(e.ItemIndex)
    End Sub
    
    private void dataRepeater1_ItemsRemoved(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterAddRemoveItemsEventArgs e)
    {
        Employees.RemoveAt(e.ItemIndex);
    }
    
  8. 对于控件级验证,可选择为子控件的 Validating 事件实现处理程序。 代码与下面的示例类似。

    Private Sub Text_Validating(
        ByVal sender As Object, 
        ByVal e As System.ComponentModel.CancelEventArgs
      ) Handles txtFirstName.Validating, txtLastName.Validating
    
        If txtFirstName.Text = "" Then
            MsgBox("Please enter a name.")
            e.Cancel = True
        End If
    End Sub
    
    private void Text_Validating(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (txtFirstName.Text == "")
        {
            MessageBox.Show("Please enter a name.");
            e.Cancel = true;
        }
    }
    

请参见

参考

ItemValuePushed

NewItemNeeded

ItemValueNeeded

概念

DataRepeater 控件简介 (Visual Studio)