2010-05-11 46 views
1

我使用ListView在列表中显示项目。用户可以自己选择项目,或使用某些“预选键”来选择具有指定属性的项目。WPF Listview - 选择'field of view'外的项目

要检查的项目我使用类似的东西:

for(int i;i<MyListView.Items.Count;++i) 
{ 
    if(/*... Check if the items should be selected ...*/) 
     (MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true; 
} 

这完全适用的项目,是在excecution时可见。但对于不可见的项目,ContainerFromIndex()返回null。我听说这与虚拟化有关,并且该列表不知道“视野”上的项目是否有利或不利。但是,如果您手动选择它们,可能会在列表的“视野”旁边选择列表中的项目?

以及如何选择“视野”以外的项目?我认为这一定是可能的。

感谢您的帮助, 商标

回答

2

正如你所说,我的猜测是,这个问题是ListView的项目的虚拟化。默认情况下,ListView(和ListBox)使用VirtualizingStackPanel作为它们的ItemsPanel来提高性能。有关其工作原理的简要说明可以阅读here

但是,您可以替换另一个面板。在这种情况下,请尝试使用正常的StackPanel。如果ListView中有大量项目,特别是如果它们是复杂项目,性能可能会受到一些影响。

<ListView> 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel/> 
     </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
</ListView> 

编辑

您也可以尝试的解决方案描述at this similar question,这取决于你的模型。但是,这可能不适合你。

+0

但是,怎么可能呢,当我选择一个项目时,将它滚动到视线之外并且向后滚动,它仍然被选中?某处必须存储这些信息。这真的不可访问吗? – Marks 2010-05-11 11:47:54

+0

那么,选定的项目可以通过'SelectedItems'访问。它返回一个IList,它有一个Add()方法。你尝试添加你想要选择的项目吗?这意味着你必须从你在ListView中显示的任何集合中添加项目到这个IList。可能没有办法只使用索引来完成它。 – 2010-05-11 19:04:51

+0

感谢这个答案,这一直让我疯狂。 – Mark 2013-04-11 15:48:05

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; 
} 

我不是很满意,需要通过视觉树搜索找到的面板,但我不知道任何其他方式得到它,也不在处理虚拟化面板时滚动到特定索引。