2009-08-11 7 views
10

Ich habe eine DataGridView, deren Datenquelle eine BindingList ist. MyObj hat einige Nullable-Eigenschaften (wie int? Und DateTime?). Ich möchte die Sortierung in meine Bindungsliste implementieren, sodass DataGridView die Spalte sortieren kann, wenn der Benutzer auf die Spaltenüberschrift klickt.Int32? mit IComparable

Nach einigem Suchen fand und befolgte ich die Antwort auf diese Frage (DataGridView Column sorting with Business Objects).

Ich kann diese Lösung nicht für Nullable Typen arbeiten, da sie IComparable nicht implementieren. Auch für Klassen, die IComparable wie String implementieren, schlägt ApplySortCore (...) fehl, wenn der String einen Nullwert hat.

Gibt es dafür eine Lösung? Oder muss ich eine Wrapper-Klasse für "Int32?" ?

zB

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 
} 

Antwort

11

Nullable<int> kann IComparable nicht implementieren, aber sicher int tut. Und Nullable<T> immer Boxen zu T (zum Beispiel, wenn Sie auf eine Schnittstelle wie IComparable, die eine Box-Konvertierung ist). Das Vergleichen/Sortieren von nullbaren Eigenschaften sollte daher kein Problem darstellen.

int? value = 1; 
IComparable comparable = value; // works; even implicitly 

Also, die Überprüfung in der Probe an der Spitze funktioniert nicht richtig. Versuchen Sie folgendes:

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 

Noch eine Ergänzung: wenn Sie NULL-Werte wollen auch arbeiten (beide String und Nullable-Typen), könnten Sie versuchen, diese Re-Implementierung von 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)); 
} 

Es gibt keine müssen direkt nach IComparable suchen, lassen Sie einfach die Sortiermethoden selbst aussortieren.

+0

Vielen Dank. Ich muss auch _sortPropertyValue = prop; _sortDirectionValue = Richtung; _isSortedValue = true; , damit der Code funktioniert. Vielen Dank :) – David

+0

Re "Vergleichen/Sortieren auf Nullable Eigenschaften sollte kein Problem sein." - es sei denn, die Eigenschaft hat den Wert "null". In diesem Fall erhalten Sie eine Laufzeitausnahme. (Ich nehme an - ich habe es nicht ausprobiert.) – ToolmakerSteve

+0

@ToolmakerSteve, 'OrderBy' und' OrderByDescending' haben nichts dagegen, wenn die Eigenschaft 'null' zurückgibt. Der Standard-Comparer, den er verwendet, sortiert oben die Werte 'null'. Sie werden nur dann ein Problem haben, wenn die Liste selbst einen 'Null'-Eintrag enthält. – Ruben

3

Wenn Ihre Nullable Types Vergleich kann man so etwas tun ...

Int32? val1 = 30; 
Int32 val2 = 50; 

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