Rac*_*hel 121 wpf virtualization itemscontrol virtualizingstackpanel
我有一个ItemsControl数据列表,我想虚拟化,但VirtualizingStackPanel.IsVirtualizing="True"似乎不适用于ItemsControl.
这是真的吗,还是有另一种方法可以做到这一点,我不知道?
要测试我一直在使用以下代码块:
<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Initialized="TextBlock_Initialized"
Margin="5,50,5,50" Text="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
如果我将其更改ItemsControl为a ListBox,我可以看到该Initialized事件只运行了几次(巨大的边距只是因此我只需要通过一些记录),但是ItemsControl每个项目都会被初始化.
我试过设置ItemsControlPanelTemplate为a VirtualizingStackPanel但似乎没有帮助.
Dav*_*idN 210
实际上它不仅仅是ItemsPanelTemplate使用它VirtualizingStackPanel.默认ControlTemplate为ItemsControl不具备ScrollViewer,这是关键的虚拟化.添加到默认控件模板ItemsControl(使用控件模板ListBox作为模板)为我们提供以下内容:
<ItemsControl
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"
ItemsSource="{Binding Path=AccountViews.Tables[0]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock
Initialized="TextBlock_Initialized"
Text="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer
Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
(BTW,一个查看默认控件模板的好工具是Show Me The Template)
需要注意的事项:
你必须设置ScrollViewer.CanContentScroll="True",看到这里的原因.
还要注意我放了VirtualizingStackPanel.VirtualizationMode="Recycling".这将减少TextBlock_Initialized调用的次数,但是在屏幕上可以看到许多TextBlock.你可以阅读更多的UI虚拟这里
.
编辑:忘了不言自明的:作为一个替代的解决方案,只需更换ItemsControl与ListBox:)另外,看看这个MSDN页面上优化性能,请注意,ItemsControl是不是在"控件实现性能特点"表,这是为什么我们需要编辑控件模板.
Zod*_*man 33
基于DavidN的答案,这里有一个样式,您可以在ItemsControl上使用它来虚拟化它:
<!--Virtualised ItemsControl-->
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True"
>
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
我不喜欢使用ListBox的建议,因为它们允许选择您不一定需要的行.
| 归档时间: |
|
| 查看次数: |
50106 次 |
| 最近记录: |