jay*_*ars 6 wpf listbox ui-virtualization virtualizingstackpanel
我使用StackPanel垂直布局几个控件(即标题,子标题,列表框,分隔符,列表框等).
StackPanel是ScrollViewer的子代,以确保其内容始终可滚动.
StackPanel中的一个控件是ListBox.
其ItemsSource是绑定到大型集合的数据,复杂的DataTemplate用于实现每个项目.
不幸的是,我的性能(高CPU /内存)非常糟糕.
我试过了
但是表演没有区别.我猜测StackPanel在测量期间给它的内部儿童无限高度?
当我用其他面板/布局(例如,Grid,DockPanel)替换ScrollViewer和StackPanel并且性能显着提高时,这让我相信瓶颈和解决方案都在虚拟化中.
有什么方法可以改善这个视图的CPU /内存性能吗?

[更新1]
原始示例项目:http://s000.tinyupload.com/index.php?file_id = 29810707815310047536
[更新2]
我尝试重新设置/模板化TreeView/TreeViewItems来提供以下示例.它仍然需要很长时间才能启动/使用相同的高内存.但是一旦加载,滚动感觉比原始样本响应更快.
想知道是否还有其他方法可以进一步改善启动时间/内存使用情况?
重新设计的TreeView项目:http://s000.tinyupload.com/index.php?file_id = 00117351345725628185
[更新2]
pushpraj的解决方案就像一个魅力
pus*_*raj 14
您可能会限制巨大列表框的最大大小并启用 Virtualization
例如
<ListBox MaxHeight="500"
VirtualizingPanel.IsVirtualizing="true"
VirtualizingPanel.VirtualizationMode="Recycling" />
Run Code Online (Sandbox Code Playgroud)
这将使ListBox仅加载一些项目,并将启用列表框上的滚动条以滚动到其他项目(如果需要).
同时设置VirtualizationMode为Recycling将帮助您重用复杂的数据模板,从而无需为每个项目重新创建它们.
编辑
这里是一个基于你的样本的解决方案,我用CompositeCollection它Virtualization来实现所需的.
XAML
<Grid xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:l="clr-namespace:PerfTest">
<Grid.Resources>
<DataTemplate DataType="{x:Type l:Permission}">
<StackPanel Orientation="Horizontal">
<CheckBox />
<TextBlock Text="{Binding Name}" />
<Button Content="+" />
<Button Content="-" />
<Button Content="..." />
</StackPanel>
</DataTemplate>
<CompositeCollection x:Key="data">
<!-- Content 1 -->
<TextBlock Text="Title"
FontSize="24"
FontWeight="Thin" />
<!-- Content 2 -->
<TextBlock Text="Subtitle"
FontSize="16"
FontWeight="Thin" />
<!-- Content 3 -->
<CollectionContainer Collection="{Binding DataContext, Source={x:Reference listbox}}" />
<!-- Content 4 -->
<TextBlock Text="User must scroll past the entire list box before seeing this"
FontSize="16"
FontWeight="Thin"
Padding="5"
TextWrapping="Wrap"
Background="#99000000"
Foreground="White" />
</CompositeCollection>
</Grid.Resources>
<ListBox x:Name="listbox"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{StaticResource data}" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var items = new ObservableCollection<Permission>();
foreach (var i in Enumerable.Range(0, 10000).Select(i => new Permission() { Name = "Permission " + i }))
{ items.Add(i); }
DataContext = items;
}
}
public class Permission
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因为我们无法为字符串创建数据模板所以我将字符串集合更改为Permission集合.我希望在你的真实项目中它会有类似的东西.
尝试一下,看看这是否接近你所需要的.
注意:如果有任何设计师警告,您可以放心地忽略 Collection="{Binding DataContext, Source={x:Reference listbox}}"