DataRepeater 控件中的虚拟模式 (Visual Studio)
如果要在 DataRepeater 控件中显示大量表格数据,可通过将 VirtualMode 属性设置为 True 并显式管理该控件与其数据源的交互来提高性能。 DataRepeater 控件提供若干事件,您可以处理这些事件来与数据源交互并根据需要在运行时显示数据。
虚拟模式的工作原理
DataRepeater 控件最常见的用法是在设计时将 ItemTemplate 的子控件绑定到数据源并使 BindingSource 可以根据需要来回传递数据。 使用虚拟模式时,控件不绑定到数据源,数据在运行时传入或传出底层数据源。
VirtualMode 属性设置为 True 时,您可以通过从**“工具箱”添加控件来创建用户界面,而不从“数据源”**窗口添加绑定控件。
事件的引发是基于控件的,并且您必须添加代码来处理数据的显示。 当某个新的 DataRepeaterItem 滚动到视图中时,将为每个控件引发一次 ItemValueNeeded 事件,因此您必须在 ItemValueNeeded 事件处理程序中为每个控件提供值。
如果用户更改了某个控件中的数据,将引发 ItemValuePushed 事件,因此您必须验证数据并将它保存到数据源中。
如果用户添加新项,将引发 NewItemNeeded 事件。 使用此事件的处理程序在数据源中创建新记录。 若要防止意外更改,还必须监视每个控件的 KeyDown 事件,并在用户按 Esc 键时调用 CancelEdit。
如果数据源发生更改,则可通过调用 BeginResetTemplateItem 和 EndResetTemplateItem 方法来刷新 DataRepeater 控件。 必须按顺序调用这两种方法。
最后,您还必须实现 ItemsRemoved 事件的事件处理程序,该事件在删除项时发生;还可以选择实现 UserDeletingItems 和 UserDeletedItems 事件的事件处理程序,这两个事件在用户通过按 Delete 键删除项时发生。
实现虚拟模式
下面是实现虚拟模式所需的步骤。
实现虚拟模式
从**“工具箱”的“Visual Basic PowerPacks”**选项卡中将 DataRepeater 控件拖到窗体或容器控件中。 将 VirtualMode 属性设置为 True。
从**“工具箱”**中将控件拖到 DataRepeater 控件的项模板区域(上半部分区域)。 您需要为数据源中要显示的每个字段分别添加一个控件。
为 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; } } }
为 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; } }
分别为每个子控件的 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(); } }
为 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; }
为 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); }
对于控件级验证,可选择为子控件的 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; } }