注意:修正了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应该在其中工作
答案 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。