wpf - 是否可以覆盖 ItemsPresenter 以使用 Virtualizing StackPanel 而不是常规堆栈面板?

标签 wpf virtualizingstackpanel itemspresenter

背景

我有一个自定义控件,它继承自 TreeView 并被修改为以数据网格样式显示。我看到的问题是扩展树时的性能。这在我对 Tree Views 的研究中很常见。在使用 WPF 性能工具进行检查后,我注意到 ItemsPresenter 类使用的是常规堆栈面板而不是虚拟化堆栈面板。

enter image description here

这是使用 ScrollContentPresenter 的代码部分(如图所示)。

<ScrollContentPresenter Name="PART_ScrollContentPresenter"
      KeyboardNavigation.DirectionalNavigation="Local"
      Content="{TemplateBinding Content}"
      ContentTemplate="{TemplateBinding ContentTemplate}"
      CanContentScroll="{TemplateBinding CanContentScroll}"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

这是传入的模板。

    <ControlTemplate TargetType="CommonControls:TreeListViewItem508">
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Border x:Name="item">
            <Border Name="InnerBorder">
                <Grid Style="{StaticResource GridBackgroundStyle}">
                    <Rectangle Visibility="Collapsed" Fill="#75FFFFFF" Name="UpperHighlight" />
                </Grid>
            </Border>
        </Border>
        <ItemsPresenter Grid.Row="1" Name="ItemsHost" />
    </Grid>
</ControlTemplate>

问题

是否可以强制项目展示者使用虚拟化堆栈面板?

注意事项

  • 我已经尝试将 ItemsPresenter 包装在 ScrollViewer 中,但这会产生不希望的结果(每行都有滚动条)。
  • 我将选项 CanContentScroll = true 硬编码为测试,因为当它设置为 false 时会禁用虚拟化。
  • 此控件正在生产中并在多个地方使用,因此我目前无法选择替换/重写/或对设计进行重大修改。如果可能,我只是想覆盖这一节。

非常感谢任何建议或选项。

已解决:

我通过将此添加到样式来修改模板的样式,并将堆栈面板切换为虚拟化。

 <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>

最佳答案

您可以使用 VirtualizingStackPanel,但请注意 there is more to virtualizing a StackPanel than just using a VirtualizingStackPanel

这是一个使用上面发布的链接中找到的代码的示例,其中列出了所需的项目:

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

关于wpf - 是否可以覆盖 ItemsPresenter 以使用 Virtualizing StackPanel 而不是常规堆栈面板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9503433/

相关文章:

c# - Wpf 功能区应用程序 - 不允许我向功能区添加内容!

c# - 显示 WPF TextBox 的剩余字符,该文本框的 MaxLength 受到限制

c# - Treeview 上的 VirtualizingStackPanel 不是虚拟化

wpf - 不裁剪项目的虚拟化面板

wpf - 使用网格作为 ItemsHost

windows-phone-7 - ListBox的ControlTemplate样式时如何保持虚拟化?

c# - 如何隐藏 Owner 最小化后显示的 Owned 窗口?

c# - 如何为 Dialog 服务 MVVM Light 编写测试用例

WPF Listview 虚拟化模式在绑定(bind)时会出现问题

c# - WPF - 为 ItemsPresenter 实现 ItemTemplate?