2009-08-11 73 views
10

我有一个DataGridView其数据源是一个BindingList。 MyObj有几个可为空的属性(如int?和DateTime?)我想实现对绑定列表的排序,因此DataGridView可以在用户单击列标题时对列进行排序。Int32?与IComparable

经过一番挖掘,我发现并遵循了这个问题的答案(DataGridView Column sorting with Business Objects)。

我不能得到该解决方案工作的Nullable类型,因为他们没有实现IComparable。即使对于实现类似String的IComparable的类,当String具有null值时,ApplySortCore(...)也会失败。

有没有解决方案呢?或者我必须为“Int32?”实现包装类?

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 
} 

回答

11

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,只需让排序方法自己排序即可。

+0

非常感谢。我还需要设置_sortPropertyValue = prop; _sortDirectionValue =方向; _isSortedValue = true; 为了代码工作。非常感谢:) – David 2009-08-12 13:43:04

+0

重新“对可空属性进行比较/排序不应该是一个问题。” - 除非该属性的值为null,否则您将得到一个运行时异常。 (我假设 - 我没有尝试过。) – ToolmakerSteve 2016-11-02 19:24:56

+0

@ToolmakerSteve,'OrderBy'和'OrderByDescending'不介意属性何时返回null。它使用的默认比较器将排序顶部的'null'值。只有当列表本身包含一个'null'条目时,才会出现问题。 – Ruben 2016-11-04 10:09:37

3

在比较你可空类型,你可以做这样的事情......

Int32? val1 = 30; 
Int32 val2 = 50; 

Int32 result = (val1 as IComparable).CompareTo(val2);