虚拟模式下的行与遍历
上一节讲到,行也有Name属性,这样我们可以快速获取指定名称的行。
不过在虚拟模式下,要获取指定名称的行,可能付出一些代价。
以上一节的代码为例:
Dim
lv As
WinForm.ListView
= e.Form.Controls("ListView1")
Dim
id As
String = Tables("员工").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的互动极少,