我正在使用itemscontrol来保存大量不同的控件。我决定启用虚拟化,因为我需要显示的控件数量(在某些情况下需要花费一秒左右来“加载”控件,我真的需要将它们显示在长列表中而不是使用某种类型崩溃)。
下面是对我所拥有的一个简单测试(我正在使用提到的反射黑客here)。问题是垂直滚动条上的拇指在您拖动时会更新,我认为这是有道理的,因为当新的控件进入视图时,滚动查看器本身正在快速更新,但我想知道是否有解决方案?
是否可以进行虚拟化,基于像素的滚动和拇指,其大小反映所有控件而不仅仅是其处理的控件?
public class A { public double Height { get; set; } };
public partial class MainWindow : Window
{
public List<A> Data { get; set; }
public MainWindow()
{
var r = new Random();
Data = new List<A>();
for (int i = 0; i < 250; ++i)
{
Data.Add(new A() { Height = r.Next(10, 500) });
}
DataContext = this;
InitializeComponent();
}
}
<ItemsControl ItemsSource="{Binding Data}" VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel local:PixelBasedScrollingBehavior.IsEnabled="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<UniformGrid Columns="4">
<Label Content="label" Height="{Binding Height}"/>
<TextBox />
<UniformGrid Rows="2">
<Button />
<Button />
</UniformGrid>
<Slider/>
</UniformGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
作为次要问题。为了看看虚拟化被禁用了多长时间,我从StackPanel派生,并定时测量/排列函数,发现所有加载时间都花在这些函数上。在我的情况下,测量600毫秒和安排200毫秒。 WPF分析工具也指出布局是杀手。这似乎是一个非常漫长的时间。不可否认,渲染250个控件(根据Snoop的10k元素)不是你最想做的事情,但任何人都可以解释为什么需要这么长时间?是否在创建新控件时更新整个布局?我玩过Slider控件的一些自定义模板,尝试减少它使用的元素的数量,但是我失去了功能。