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

更新:2007 年 11 月

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

虚拟模式的工作原理

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

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

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

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

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

最后,您还必须实现 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(ByVal sender As Object, _
     ByVal e As System.EventArgs) 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;
        }
    }
    

请参见

概念

DataRepeater 控件简介 (Visual Studio)

参考

ItemValuePushed

NewItemNeeded

ItemValueNeeded

修订记录

日期

修订

原因

2008 年 7 月

新增主题。

SP1 功能更改。