我有一个 DataGridView,其数据源是 BindingList。 MyObj 有一些可为 null 的属性(如 int?和 DateTime?) 我想对我的绑定列表实现排序,以便当用户单击列标题时 DataGridView 可以对列进行排序。
经过一番挖掘后,我找到并遵循了这个问题的答案(DataGridView 使用业务对象进行列排序 https://stackoverflow.com/questions/280948/datagridview-column-sorting-with-business-objects).
我无法让该解决方案适用于 Nullable 类型,因为它们没有实现 IComparable。即使对于像 String 这样实现 IComparable 的类,当 String 具有 null 值时,ApplySortCore(...) 也会失败。
有解决办法吗?或者我是否必须为“Int32”实现一个包装类? ?
eg
public class Int32Comparable : IComparable
{
public int? Value { get; set; }
#region IComparable<int?> Members
public int CompareTo(object other)
{
// TODO: Implement logic here
return -1;
}
#endregion
}
Nullable<int>
可能不会实施IComparable
,但可以肯定的是int
做。和Nullable<T>
总是装箱到T
(例如,当您投射到接口时,例如IComparable
,这是拳击转换)。因此,对可为空的属性进行比较/排序应该不是问题。
int? value = 1;
IComparable comparable = value; // works; even implicitly
因此,顶部示例中的检查无法正常工作。尝试这个:
Type interfaceType = prop.PropertyType.GetInterface("IComparable");
// Interface not found on the property's type. Maybe the property was nullable?
// For that to happen, it must be value type.
if (interfaceType == null && prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
// Nullable.GetUnderlyingType only returns a non-null value if the
// supplied type was indeed a nullable type.
if (underlyingType != null)
interfaceType = underlyingType.GetInterface("IComparable");
}
if (interfaceType != null)
// rest of sample
另一项补充:如果您希望空值也能工作(字符串和可为空类型),您可以尝试重新实现SortCore(...)
:
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
IEnumerable<MyClass> query = base.Items;
if (direction == ListSortDirection.Ascending)
query = query.OrderBy( i => prop.GetValue(i) );
else
query = query.OrderByDescending( i => prop.GetValue(i) );
int newIndex = 0;
foreach (MyClass item in query)
{
this.Items[newIndex] = item;
newIndex++;
}
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
无需寻找IComparable
直接让排序方法自己排序就可以了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)