我一直在研究WPF的TreeView控件中的UI虚拟化功能,据我所知,这个功能从.NET 3.5 SP1开始就可用。
我做了一个简单的项目来确保UI虚拟化被正确执行,发现它根本不起作用-所有项目都被检索出来,而不仅仅是当前显示在屏幕上的项目。
我的XAML代码如下:
请注意,
如果我用ListBox替换TreeView,UI虚拟化就像预期的那样工作 - 即只请求大约20个项目而不是全部1000个。
我做了一个简单的项目来确保UI虚拟化被正确执行,发现它根本不起作用-所有项目都被检索出来,而不仅仅是当前显示在屏幕上的项目。
我的XAML代码如下:
<TreeView x:Name="myTree" Height="150" ItemsSource="{Binding Items}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard"
ScrollViewer.IsDeferredScrollingEnabled="True" />
我的代码后台
public IEnumerable Items { get; set; }
public MainWindow()
{
Items = GenerateList();
this.DataContext = this;
InitializeComponent();
}
private IEnumerable GenerateList()
{
MyList list = new MyList();
for (int i = 0; i < 1000; i++)
{
list.Add("Item " + i);
}
return list;
}
请注意,
MyList
是我自己实现的IList
,它持有一个ArrayList
,仅转发对持有的ArrayList
的调用,并将调用的方法/属性写入控制台。例如:public object this[int index]
{
get
{
Debug.WriteLine(string.Format("get[{0}]", index));
return _list[index];
}
set
{
Debug.WriteLine(string.Format("set[{0}]", index));
_list[index] = value;
}
}
如果我用ListBox替换TreeView,UI虚拟化就像预期的那样工作 - 即只请求大约20个项目而不是全部1000个。
我做错了什么吗?
编辑
我也尝试将默认的ItemsPanel
替换为建议的VirtualizingStackPanel
,但结果相同。
IsItemsHost="True"
,但我认为在这种情况下没有任何影响 - 如果我错了请纠正我)。抱歉我没有提到它。 - Adi LesterItemsPanelTemplate
,只需设置VirtualizingStackPanel.IsVirtualizing
即可。 - H.B.ItemsSource
获取项目的行为对于ListBox
和TreeView
是相同的。出于某种奇怪的原因,看起来并不是这样。然而,我现在认为我明白了,这种行为与UI虚拟化无关,而与ItemsControls
有关。 - Adi Lester