c# SortableBindingList 无法对具有 Object 值的列进行排序
本文关键字:排序 Object SortableBindingList | 更新日期: 2023-09-27 18:32:54
我有一个填充了SortableBindingList
的DataGridView
组件,如SQL Server SDK中所示,Microsoft.SqlServer.Management.Controls
。此类还用作 XML 序列化的根节点。
列表的成员的类型具有两个基元字段和一个对象字段。包含基元值的列按预期排序。但是,对包含对象字段的列进行排序时,会引发以下异常:
System.InvalidOperationException was unhandled
Message=Failed to compare two elements in the array.
Source=mscorlib
StackTrace:
at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
at System.Collections.Generic.List`1.Sort(Comparison`1 comparison)
at Microsoft.SqlServer.Management.Controls.SortableBindingList`1.ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
at System.ComponentModel.BindingList`1.System.ComponentModel.IBindingList.ApplySort(PropertyDescriptor prop, ListSortDirection direction)
at System.Windows.Forms.BindingSource.ApplySort(PropertyDescriptor property, ListSortDirection sort)
...
InnerException: System.ArgumentException
Message=At least one object must implement IComparable.
Source=mscorlib
StackTrace:
at System.Collections.Comparer.Compare(Object a, Object b)
at Microsoft.SqlServer.Management.Controls.SortableBindingList`1.<>c__DisplayClass1.<GetComparisionDelegate>b__0(T t1, T t2)
at System.Array.FunctorComparer`1.Compare(T x, T y)
at System.Collections.Generic.ArraySortHelper`1.SwapIfGreaterWithItems(T[] keys, IComparer`1 comparer, Int32 a, Int32 b)
at System.Collections.Generic.ArraySortHelper`1.QuickSort(T[] keys, Int32 left, Int32 right, IComparer`1 comparer)
at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
从堆栈跟踪中似乎相当清楚地看出,正在比较的对象不是IComparable
- 除了它们是。或者至少他们应该是。有问题的类如下:
using System;
using System.Xml.Serialization;
namespace myapp.xmlobjects {
[XmlType("error_after")]
public class ErrorAfterObject : IComparable<ErrorAfterObject> {
[XmlAttribute("hours")]
public int Hours { get; set; }
[XmlAttribute("minutes")]
public int Minutes { get; set; }
public ErrorAfterObject() { }
public ErrorAfterObject(int hours, int minutes) {
this.Hours = hours;
this.Minutes = minutes;
}
public override string ToString() {
return string.Format("{0} hr {1} min", this.Hours, this.Minutes);
}
public int CompareTo(ErrorAfterObject other) {
return (this.Hours*60 + this.Minutes).CompareTo(other.Hours*60 + other.Minutes);
}
}
}
作为健全性检查,我在数据绑定后添加了以下调试代码:
Console.WriteLine(myGridView.Rows[0].Cells[2].ValueType.ToString());
它回来了,就像我期望的那样myapp.xmlobjects.ErrorAfterObject
。
三个问题可能有助于解决问题:我的对象是否被键入为无法比较的对象?是否可以准确检查正在比较的对象类型?我在IComparable
实施中遗漏了什么吗?
提前谢谢。
事实证明,IComparable
和IComparable<T>
不是一回事。将类定义替换为:
public class ErrorAfterObject : IComparable
以及比较方法:
public int CompareTo(object other) {
if(this.GetType() != other.GetType()) {
return Comparer.Default.Compare(this, other);
}
return (this.Hours*60 + this.Minutes).CompareTo(
((ErrorAfterObject)other).Hours*60 + ((ErrorAfterObject)other).Minutes);
}
如人们所期望的那样工作。