【发布时间】:2012-03-23 23:33:18
【问题描述】:
我有一个绑定到可观察对象列表的 DataGrid。如果我还有一个 ItemsControl 绑定到该列表,则排序性能(通过单击 DataGrid 标题)非常糟糕(对于下面的示例,大约需要几秒钟)。当 ItemsControl 没有绑定到同一个列表时,排序是即时的。
这里是一些展示这种行为的示例代码
namespace LargeDataGridViewTest
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainPresenter();
}
}
public class MainPresenter : INotifyPropertyChanged
{
private readonly ObservableCollection<Item> _items = new ObservableCollection<Item>();
public IEnumerable<Item> Items { get { return _items; } }
public MainPresenter()
{
for (var i = 0; i < 10000; i++)
_items.Add(new Item());
}
}
public class Item : INotifyPropertyChanged
{
public int Random { get; private set; }
private static readonly Random Rand = new Random();
public Item()
{
Random = Rand.Next(0, 1000000);
}
}
}
以及对应的XAML
<Window.Resources>
<DataTemplate DataType="{x:Type LargeDataGridViewTest:MainPresenter}">
<DockPanel>
<DataGrid ItemsSource="{Binding Items}"/>
<!--ListBox ItemsSource="{Binding Items}"/-->
<ItemsControl ItemsSource="{Binding Items}"/>
</DockPanel>
</DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding}"/>
如果我使用 ListBox 而不是 ItemsControl,则排序性能很好。如果我使用 ListBox 但通过例如更改 ItemsPanelTemplate 访问它的底层 ItemsControl,则性能再次变差。
如果我获取列表的浅表副本(引用相同的项目)并将 ItemsControl 绑定到该列表,则性能再次良好。
通过 EQATEC 分析器运行较慢的 ItemsControl 绑定和快速的 ListBox 绑定显示,除了顶级应用时间之外,性能没有差异。
有人知道这里发生了什么吗?
编辑
部分答案似乎是 ItemsControls 没有虚拟化,因此必须绘制所有项目而不仅仅是可见的项目。在这种情况下,为什么在DataGrid排序的时候重绘所有的ItemsControl项(即使ItemsControl的绑定方式是OneTime)?我怎样才能阻止这对 DataGrid 排序的性能产生影响?
【问题讨论】: