Можно ли переопределить ItemsPresenter, чтобы использовать виртуализирующую StackPanel вместо обычной панели стека?
-
14-11-2019 - |
Вопрос
Фон
У меня есть пользовательский элемент управления, который наследуется от 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>
Решение
Пытаться
<TreeView>
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
</TreeView>
или
<TreeView VirtualizingStackPanel.IsVirtualizing="True">
Очевидно, замените TreeView на имя вашего элемента управления древовидным представлением.
надеюсь, это поможет
Павел
Другие советы
Вы можете использовать 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>