您可能会限制巨大列表框的最大大小并启用Virtualization
例如
<ListBox MaxHeight="500"
VirtualizingPanel.IsVirtualizing="true"
VirtualizingPanel.VirtualizationMode="Recycling" />
这将使 ListBox 仅加载几个项目,并在需要时启用列表框上的滚动条滚动到其余项目。
同时设置VirtualizationMode
为Recycling
将帮助您重用复杂的数据模板,从而无需为每个项目重新创建它们。
编辑
这是基于您的示例的解决方案,我已经使用CompositeCollection
withVirtualization
来实现所需的。
xml
<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>
代码
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; }
}
由于我们无法为字符串创建数据模板,所以我将字符串集合更改为Permission
集合。我希望在你的实际项目中它会是类似的。
试一试,看看这是否接近您的需要。
注意:如果有任何设计师警告,您可以放心地忽略Collection="{Binding DataContext, Source={x:Reference listbox}}"