У меня есть 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}"/>
Если вместо ItemsControl я использую ListBox, производительность сортировки будет хорошей. Если я использую ListBox, но получаю доступ к лежащему в его основе ItemsControl, например, изменяя ItemsPanelTemplate, производительность снова ухудшается.
Если я возьму поверхностную копию списка (ссылаясь на те же элементы) и вместо этого свяжу ItemsControl с этим, производительность снова будет в порядке.
Запуск медленной привязки ItemsControl и быстрой привязки ListBox через профилировщик EQATEC не показывает разницы в производительности, кроме времени приложения верхнего уровня.
Кто-нибудь знает, что здесь происходит?
EDIT
Часть ответа, похоже, заключается в том, что ItemsControls не виртуализированы и, следовательно, должны рисовать все свои элементы, а не только видимые. В этом случае, почему все элементы ItemsControl перерисовываются при сортировке DataGrid (даже если режим привязки ItemsControl - OneTime)? И как я могу остановить это, влияя на производительность сортировки DataGrid?