2

背景

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

在此处输入图像描述

这是使用 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>
4

2 回答 2

4

您可以使用VirtualizingStackPanel,但请注意,虚拟化 StackPanel 不仅仅是使用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>
于 2012-02-29T17:19:00.793 回答
3

尝试

      <TreeView>
        <TreeView.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel/>
            </ItemsPanelTemplate>
        </TreeView.ItemsPanel>
    </TreeView>

或者

<TreeView VirtualizingStackPanel.IsVirtualizing="True">

Obviosuly 用您的树视图控件名称替换 TreeView。

希望有帮助

保罗

于 2012-02-29T17:12:31.213 回答