我正在使用虚拟模式下的 ListView (.NET 4.6)。
我试图在虚拟 ListView 中找到 Items 的索引:当我输入一个字母时,应该选择第一个带有以该字母开头的文本的项目。
这是FindItemWithText
在listView1_KeyDown
:
if (char.IsLetterOrDigit(e.KeyChar))
{
var str = e.KeyChar.ToString();
if (tempStr != str)
{
Index = 0;
tempStr = str;
}
var item = listView1.FindItemWithText(str, false, Index, true);
if (item != null)
{
item.Selected = true;
item.Focused = true;
item.EnsureVisible();
Index = item.Index + 1;
}
}
这是我的 SearchForVirtualItem 方法:
var item = lvis.OfType<ListViewItem>().FirstOrDefault(
i => i.Text.ToLower().StartsWith(e.Text.ToLower()) &&
i.Index >= e.StartIndex);
if (item == null)
{
}
else
{
e.Index = item.Index;
}
如果结果是我滚动所有代码之前的可见项目之一,我可以选择结果项目。但是,如果结果不可见并且我根本没有滚动任何内容,则该方法将返回 null。
但是,如果我滚动到列表的末尾,即使我可以获得以前无法获得的项目的索引。
示例:如果我在虚拟列表中有 200 个项目(从 200 个 ListViewItem 的列表中填充)并且只有前 50 个可见,如果我按下
c
字母并且以c
字母开头的项目在前 50 个中,它们将被选中。
但是如果我按下x
并且虚拟 ListView 中的项目在最后50
,该方法将返回null
。如果我将列表滚动到末尾,然后按,将选择x
以开头的项目。x
为什么我必须至少显示一次该项目才能有索引而不是index = -1?
这是虚拟 ListView 的正常行为还是有什么问题?
附带问题,正常模式下的 ListView 什么时候变慢?在100,000
物品之后,还是1,000,000
物品?
Edit1:
这是我的listView1_RetrieveVirtualItem
代码:
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
if (lvis.Count > 0)
{
e.Item = lvis[e.ItemIndex];
}
}
我不使用缓存。
我使用 BackGroundWorker 从 SQLite 数据库中获取数据;我创建 ListViewitems 并将它们添加到 List ( var lvis = new List<ListViewItem>
) 中。
RunWorkerCompleted
方法 :
private void Pl_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
var obj = e.Result;
if (obj != null)
{
RemoveSelection();
lvis = (List<ListViewItem>)obj;
listView1.Items.Clear();
listView1.VirtualListSize = lvis.Count;
listView1.Invalidate();
var No_of_items = listView1.Items.Count + " pin(s)";
count.Text = No_of_items;
tabLabel.Text = GetButton().Text + " | " + No_of_items;
}
}
lvis
是虚拟 ListView 从中获取数据的来源。