WPF列表视图 - 选择“视野”外的项目

时间:2010-05-11 09:43:29

标签: wpf listview listviewitem itemcontainergenerator

我正在使用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。我听说这与虚拟化有关,并且列表不知道项目的上升或下行“视野”。但是,当你手动选择它们时,怎么可能让列表中的选定项目越过“视野”?

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

感谢您的帮助, 标记

2 个答案:

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

我不太满意需要搜索可视化树来查找面板,但我不知道有任何其他方法可以获取它,也不会在处理虚拟化面板时滚动到特定索引