Reputation: 748
Note: Fixed the SummeryName typo to avoid confusion.
I'm trying to make a simple DataGrid bound to an ObservableCollection sortable by column. It's a simple setup:
<DataGrid ItemsSource="{Binding Path=DocuObjects}" CanUserSortColumns="True" SelectedItem="{Binding Path=SelectedDocu}" AutoGenerateColumns="false">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" SortMemberPath="SummaryName" Width="*" Binding="{Binding SummaryName}" />
</DataGrid.Columns>
</DataGrid>
The binding source is a simple collection:
public ObservableCollection<DocuObject> DocuObjects
{
get { return m_Docus; }
set
{
m_Docus= value;
RaisePropertyChanged("DocuObjects");
}
}
Every time I click on the column header, I get an exception:
System.Windows.Data Error: 55 : Cannot sort by 'SummaryName' InvalidOperationException:'System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: At least one object must implement IComparable.
So obviously the next step I'm taking it to implement IComparable in the DocuObject class, as the exception suggests. But that doesn't seem to do anything, regardless of whether I add IComparable or IComparable. The exception still occurs, and my CompareTo() code doesn't get hit when I add a breakpoint.
For test purposes, I've simplified my code down to this - but that NotImplementedException is not even getting hit.
public class DocuObject: INotifyPropertyChanged, IEquatable<DocuObject>, IComparable<DocuObject>
{
...
public int CompareTo(DocuObject other)
{
throw new NotImplementedException();
}
}
What fundamental error am I making? SummaryName itself is a string, where CompareTo should work
Upvotes: 0
Views: 1665
Reputation: 1261
The MSDN documentation explains how you can allow columns to be used for sorting: https://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.canusersortcolumns(v=vs.110).aspx
You can set this sorting behavior for individual columns by setting the DataGridColumn.CanUserSort property.
Is the property actually called SummeryName
? I will continue under the assumption that is not a typo. You need to set both SortMemberPath="SummeryName"
and CanUserSort="True"
for the specific text column.
Unless your names are evocative of summer you might want to change the property from SummeryName
to SummaryName
Also I am assuming SummeryName
is a string, but if it is not then it must implement IComparable to be sorted.
Upvotes: 2
Reputation: 5236
The problem is not missing IComparable on the DocuObject...the problem is the missing IComparable on whatever object you are using for SummeryName. If you use string for SummeryName the sorting will work fine. This is because string implements IComparable.
Upvotes: 1
Reputation: 3631
But that doesn't seem to do anything, regardless of whether I add IComparable or IComparable.
Since you use SortMemberPath="SummeryName"
, it means that SummeryName
should implement IComparable
(and not IComparable). If it is a string, check for typos. If it is a custom class, DataGrid
calls CompareTo
in it:
public class CustomClass : IComparable
{
public int CompareTo(object obj)
{
//...
}
}
Upvotes: 1
Reputation: 13438
The type behind the SummeryName
property needs to implement IComparable
, not the DocuObject
type. You set SortMemberPath="SummeryName"
after all.
Upvotes: 1