尝试对DataGrid列进行排序时出现异常

时间:2017-03-05 00:23:11

标签: c# wpf datagrid

注意:修正了SummeryName拼写错误以避免混淆。

我正在尝试将一个简单的DataGrid绑定到可按列排序的ObservableCollection。这是一个简单的设置:

<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>

绑定源是一个简单的集合:

public ObservableCollection<DocuObject> DocuObjects
{
    get { return m_Docus; }
    set
    {
        m_Docus= value;
        RaisePropertyChanged("DocuObjects");                
    }               
}

每次单击列标题时,都会出现异常:

  

System.Windows.Data错误:55:无法按'SummaryName'排序   InvalidOperationException:'System.InvalidOperationException:失败   比较数组中的两个元素。 ---&GT; System.ArgumentException:At   至少有一个对象必须实现IComparable。

显然下一步我将它用于在DocuObject类中实现IComparable,正如例外情况所示。但无论我是添加IComparable还是IComparable,这似乎都没有做任何事情。异常仍然发生,并且当我添加断点时,我的CompareTo()代码不会被命中。

出于测试目的,我已将代码简化为 this - 但NotImplementedException甚至没有被命中。

public class DocuObject: INotifyPropertyChanged, IEquatable<DocuObject>, IComparable<DocuObject>
{
...
    public int CompareTo(DocuObject other)
    {
        throw new NotImplementedException();
    }
}

我犯了什么根本错误? SummaryName本身是一个字符串,CompareTo应该在其中工作

4 个答案:

答案 0 :(得分:1)

MSDN文档说明了如何允许使用列进行排序: https://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.canusersortcolumns(v=vs.110).aspx

  

您可以通过设置DataGridColumn.CanUserSort属性为各列设置此排序行为。

该属性实际上是monstersy吗?我将继续假设不是拼写错误。您需要为特定文本列设置import PlaygroundSupport import UIKit let text = "I am \"coding\" an \"iPhone\" app" let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 320, height: 320)) PlaygroundPage.current.liveView = textView let fontSize: CGFloat = 14.0 let plainFont = UIFont.systemFont(ofSize: fontSize) let boldFont = UIFont.boldSystemFont(ofSize: fontSize) var attributedText = NSMutableAttributedString(string: text, attributes: [NSFontAttributeName : plainFont]) do { let regexString = "\"(\\w*)\"" let regex = try NSRegularExpression(pattern: regexString, options: []) let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.characters.count)) for match in matches { let rangeBetweenQuotes = match.rangeAt(1) attributedText.setAttributes([NSFontAttributeName : boldFont], range: rangeBetweenQuotes) } textView.attributedText = attributedText } catch let error { print(error) } SummeryName

除非您的名字令人回想夏天,否则您可能希望将该属性从SortMemberPath="SummeryName"更改为CanUserSort="True"

此外,我假设SummeryName是一个字符串,但如果不是,那么它必须实现IComparable进行排序。

答案 1 :(得分:1)

SummeryName属性背后的类型需要实现IComparable,而不是DocuObject类型。毕竟你设置了SortMemberPath="SummeryName"

答案 2 :(得分:1)

  

但无论我是添加IComparable还是IComparable,这似乎都没有做任何事情。

由于您使用SortMemberPath="SummeryName",这意味着SummeryName应该实现IComparable(而不是IComparable)。如果是字符串,请检查拼写错误。如果是自定义类,则DataGrid会在其中调用CompareTo

public class CustomClass : IComparable
{  
    public int CompareTo(object obj)
    {
        //...
    }
}

答案 3 :(得分:1)

问题是没有丢失DocuObject上的IComparable ...问题是您在SummeryName上使用的任何对象上缺少IComparable。如果你使用字符串SummeryName,排序将正常工作。这是因为string实现了IComparable。