我正在使用ListView来显示列表中的项目。用户可以自己选择项目,或使用一些“预选键”来选择具有指定属性的项目。
检查我使用的东西:
for(int i;i<MyListView.Items.Count;++i)
{
if( /*... Check if the items should be selected ...*/ )
(MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true;
}
这适用于在执行时可见的项目。但是对于不可见的项目,ContainerFromIndex()返回null。我听说这与虚拟化有关,并且列表不知道项目的上升或下行“视野”。但是,当你手动选择它们时,怎么可能让列表中的选定项目越过“视野”?
如何选择“视野”之外的项目?我认为这一定是可能的。
感谢您的帮助, 标记
答案 0 :(得分:2)
正如您所提到的,我的猜测是问题是ListView项目的虚拟化。默认情况下,ListView(和ListBox)使用VirtualizingStackPanel
作为其ItemsPanel来提高性能。有关其工作原理的简要说明,请参阅here。
但是,您可以替换其他Panel。在这种情况下,请尝试使用普通的StackPanel。如果ListView中有大量项目,特别是如果它们是复杂的项目,性能可能会受到一些影响。
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
修改强>
您还可以尝试使用at this similar question描述的解决方案,具体取决于您的型号。但是,这可能不适合你。
答案 1 :(得分:0)
在处理虚拟化项控件时,禁用虚拟化的替代方法(有时候实际上是一个有用的功能,即使它干扰了API其他部分的正确操作)也是找到VirtualizingPanel
并明确告诉它滚动。
例如:
void ScrollToIndex(ListBox listBox, int index)
{
VirtualizingPanel panel = FindVisualChild<VirtualizingPanel>(listBox);
panel.BringIndexIntoViewPublic(index);
}
static T FindVisualChild<T>(DependencyObject o) where T : class
{
T result = o as T;
if (result != null)
{
return result;
}
int childCount = VisualTreeHelper.GetChildrenCount(o);
for (int i = 0; i < childCount; i++)
{
result = FindVisualChild<T>(VisualTreeHelper.GetChild(o, i));
if (result != null)
{
return result;
}
}
return null;
}
我不太满意需要搜索可视化树来查找面板,但我不知道有任何其他方法可以获取它,也不会在处理虚拟化面板时滚动到特定索引