I have an ObservableCollection
of ViewModels that are sitting in a WPF DataGrid
. The DataGrid
has three columns:
- Position column; this is rendered at runtime by a UserControl that displays the position of the row in my DataGrid
- Name column; this is rendered at runtime by a UserControl that displays the name of the column (yes, I need a UserControl for this based on how the name needs to be displayed, but that is an aside)
- Data column; this is rendered at runtime by yet another UserControl.
My columns are defined like this:
<toolkit:DataGrid.Columns>
<toolkit:DataGridTemplateColumn Header="" MinWidth="35" MaxWidth="35" SortMemberPath="Position.PositionIndex" CanUserSort="True">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Position}"/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
<toolkit:DataGridTemplateColumn Header="Name" MinWidth="150" Width="150" SortMemberPath="Name" CanUserSort="True">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}"/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
<toolkit:DataGridTemplateColumn Header="Data" Width="Auto" CanUserSort="False">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Data}"/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
</toolkit:DataGrid.Columns>
So, because my Row and Name columns are UserControls, the WPF DataGrid
cannot natively sort on them. So to facilitate sorting, when a column header is clicked, I do some ListCollectionView.CustomSort
magic.
Here is what my custom sorters look like for the Name column:
// Customized sorter, by name, ascending.
public class AscendingNameSorter : IComparer
{
public int Compare(object x, object y)
{
var lhs = (MyViewModel)x;
var rhs = (MyViewModel)y;
return lhs.Name.CompareTo(rhs.Name);
}
}
// Customized sorter, by name, descending.
public class DescendingNameSorter : IComparer
{
public int Compare(object x, object y)
{
var lhs = (MyViewModel)x;
var rhs = (MyViewModel)y;
return rhs.Name.CompareTo(lhs.Name);
}
}
The problem is that this is incredibly slow. I can't figure out why. With 10 items in the DataGrid
, my application grinds to a halt for 3-4 seconds while it resorts. I thought ListCollectionView.CustomSort
was supposed to be the most efficient way to sort an ObservableCollection
... where am I going wrong?