虚拟模式下的行与遍历

上一节讲到,行也有Name属性,这样我们可以快速获取指定名称的行。

不过在虚拟模式下,要获取指定名称的行,可能付出一些代价。
以上一节的代码为例:

Dim lv As WinForm.ListView = e.Form.Controls("ListView1")
Dim
id As StringTables("员工").Current("_Identify")
Dim
vr As WinForm.ListViewRow = lv.Rows(id)
vr
.Delete()

假定由于虚拟模式下,行都是需要的时候生成,上面的代码首先会在已经生成的行中查找指定名称的行,如果找到则返回,如果没有找到,则执行RetrieveVirtualRow事件,往下生成一个新的行,如果新行的名称等于指定名称,则返回此新行,否则继续生成,继续比较,直到生成一个名称相符的行,或者所有行都生成完毕。
所以上面简单的一行代码,可能会导致ListView要生成所有的行,如果ListView有几万行,可能会消耗相当长的时间。

所以在虚拟模式下,最好不要通过行的名称来引用行,而是通过行的位置,例如:

Dim lv As WinForm.ListView = e.Form.Controls("ListView1")
Dim
vr As WinForm.ListViewRow = lv.Rows(20)

但是麻烦来了,如果要获取某个DataRow对应的ListViewRow,那么如何知道DataRow对应的ListViewRow的位置呢? 这个只能用笨办法了,例如:

Dim dr As DataRow = Tables("国家").Current.DataRow
Dim
idx As Integer = -1
For
i As Integer = 0 To DataTables("国家").DataRows.Count - 1
    If DataTables("国家").DataRows(i)("_Identify") = dr("_Identify") Then
        idx = i
        Exit For
    End If

Next
If
idx >= 0 Then
    Dim lv As WinForm.ListView = e.Form.Controls("ListView1")
   
Dim vr As WinForm.ListViewRow = lv.Rows(idx)
   
vr.Delete()
End
If

此外,在虚拟模式下,我们应该尽量避免遍历所有行,例如下面的代码:

Dim lv As WinForm.ListView = e.Form.Controls("ListView1")
For
Each vr As WinForm.ListViewRow In lv.Rows
   
'代码
Next

这段代码执行过程中,会生成所有的行,因为只有这样,才能完成遍历。

当然,如果虽然用了虚拟模式,但是一次显示的行数并不多,那么可以正常使用行名称来引用行,正常遍历行,无需为感受不到的性能差别花费太多精力。

上面就是虚拟模式的一些不足,但是和其带来的好处相比,这一点不足并不算什么,而且ListView和DataTable的互动,多数是从ListView到DataTale,从DataTable到ListView的互动极少,


本页地址:http://www.foxtable.com/webhelp/topics/2826.htm