每个人都说ListBox的默认ItemsPanel是VirtualizingStackPanel。我创建了一个ListBox派生类(称之为MyListBox),它默认为StackPanel。
我的意思是我必须强制虚拟化,例如这样:
const string itemsPanelTemplateString = @"
<ItemsPanelTemplate
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
<VirtualizingStackPanel/>
</ItemsPanelTemplate>";
MyListBox {
this.ItemsPanel = (ItemsPanelTemplate)
System.Windows.Markup.XamlReader.Load(itemsPanelTemplateString);
}
我可以在这里重印我的课程,但那不是重点。我想知道一般答案。
该类不会更改预定义的ListBox样式,但它使用自己的ListBoxItem派生类。
我很确定使用虚拟化有一些条件,因为我的同事说他过去看过各自的ListBox代码。不幸的是,目前我们无法访问MS dll的调试版本。
答案 0 :(得分:1)
从ListBox派生的ListBox和控件默认情况下将VirtualizedStackPanel作为ItemsPanel,除非用户代码明确地更改它。
但是,如果您的自定义ListBox碰巧直接从ItemsControl派生(如同实际派生自ListBox),那么您将获得StackPanel作为默认的ItemsPanel。
你的代码可能就是这种情况吗?如果没有,请分享您的控制代码。
答案 1 :(得分:1)
解决。这是我的错误:
当重写ListBox.OnApplyTemplate()(用于时间测量)时,我忘记调用base.OnApplyTemplate()。显然,项目面板的选择就在那里完成。
危险的错误,因为一切似乎都有效。
感谢所有试图提供帮助的人。
答案 2 :(得分:0)
ListBox的默认样式不指定ItemsPanel模板。
根据我在反射器OnApplyTemplate
中可以看到的内部代码,如果未提供VirtualizingStackPanel
模板,则会向内部ItemsHost
分配ItemsPanel
。
或许包括你的班级代码可能是一个好主意。
答案 3 :(得分:0)
另一件需要注意的事情(显然)是,如果您绑定的集合实现IList
,您也只会获得虚拟化。