【问题标题】:ItemsControl behavior when ItemsSource is IListItemsSource 为 IList 时的 ItemsControl 行为
【发布时间】:2012-07-23 07:17:17
【问题描述】:

我正在尝试为分层控件实现一个虚拟化集合,类似于this article 中提供的常规控件。

文章中提出的解决方案在很大程度上依赖于以下行为(来自文章):

ItemsControl 绑定到 IList 实现时,而不是 IEnumerable 实现,它不会枚举整个列表, 而是只访问显示所需的项目。它使用 Count属性判断集合的大小,大概是为了 设置滚动范围。然后它将遍历屏幕 使用列表索引器的项目。因此,可以创建一个IList 可以报​​告有大量项目,但实际上只有 需要时取回物品。

我发现虽然ListBox 有这种行为,但TreeView(也是ItemsControl)的行为并非如此,并且无论是否显示所有项目都始终被请求屏幕。

那么,这是特定于 ListBox 而不是每个 ItemsControl 的行为还是 WPF 的 TreeView 中的错误?

我也无法在 MSDN 上找到任何提及此行为的内容,因此如果有人发现它记录在任何我想知道的地方。

【问题讨论】:

  • ItemsControl.ItemsPanelRemarks 部分中,它说 ListBox 的默认 ItemsPanel 是 VirtualizingStackPanel,而 here MSDN 说 TreeView 的默认 ItemsPanel 是普通的 StackPanel。
  • @Clemens 即使将TreeView.ItemsPanel 设置为VirtualizingStackPanel 并使用VirtualizingStackPanel.IsVirtualizing="True" 开启虚拟化,也会发生这种情况。
  • 好的,您可以在问题中提到这一点。

标签: wpf virtualization itemscontrol ilist itemssource


【解决方案1】:

虚拟化ItemsControl 不仅仅是使用VirtualizingStackPanel 或设置VirtualizingStackPanel.IsVirtualizing="True"

这是所需的重要代码,但请参阅this question 以获得更完整的答案

<ItemsControl
    VirtualizingStackPanel.IsVirtualizing="True" <!-- needed -->
    ScrollViewer.CanContentScroll="True" <!-- needed -->
    ... >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel /> <!-- needed -->
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
            <ScrollViewer>  <!-- needed -->
                <ItemsPresenter  />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

【讨论】:

  • 实际上,将TreeView.ItemsPanel 设置为VirtualizingStackPanelVirtualizingStackPanel.IsVirtualizing="True" 就足以在TreeView 中打开虚拟化 - 我使用了Snoop,发现TreeViewItems 只是为可见项目创建的;但显然,UI 虚拟化并不一定意味着不可见的项目不会被访问。所以我的问题不是关于 UI 虚拟化,而是更多关于如何使 TreeView 仅访问其 ItemsSource 中的可见元素(就像 ListBox 一样)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多