2008-08-14 15 views
6

WPF unterstützt das Standardsortier- oder Filterverhalten für Ansichten von CompositeCollections nicht. Es wäre also eine bewährte Methode, dieses Problem zu lösen.Sortieren einer Composite-Sammlung

Es gibt zwei oder mehr Objektsammlungen verschiedener Typen. Sie möchten diese zu einer einzigen sortierbaren und filterbaren Sammlung zusammenfassen (wobei Sie die Sortierung oder Filter manuell implementieren müssen).

Einer der Ansätze, die ich in Betracht gezogen habe, ist das Erstellen einer neuen Objektsammlung mit nur wenigen Kerneigenschaften, einschließlich derjenigen, nach denen die Auflistung sortiert werden soll, und einer Objektinstanz jedes Typs.

Und dann Schleife durch meine beiden Objekt Sammlungen, um die neue zusammengesetzte Sammlung zu erstellen. Offensichtlich ist dies eine Art Brute-Force-Methode, aber es würde funktionieren. Ich würde das gesamte Sortier- und Filterverhalten der Ansicht für meine neue zusammengesetzte Objektgruppe erhalten, und ich könnte eine Datenvorlage darauf setzen, um meine Listenelemente richtig anzuzeigen, je nachdem, welcher Typ tatsächlich in diesem zusammengesetzten Element gespeichert ist.

Welche Vorschläge gibt es, um dies eleganter zu machen?

Antwort

1

Update: Ich fand eine viel elegantere Lösung:

class MyCompositeObject 
{ 
    DateTime CreatedDate; 
    string  SomeAttribute; 
    Object  Obj1; 
{ 
class MyCompositeObjects : List<MyCompositeObject> { } 

ich, dass durch Reflexion gefunden, die spezifische Art in Obj1 gespeichert ist zur Laufzeit aufgelöst und das typspezifische DataTemplate wird wie erwartet angewendet!

1

"Brute Force" -Methode, die Sie erwähnen, ist eigentlich die ideale Lösung. Wohlgemerkt, alle Objekte befinden sich im RAM, es gibt keinen I/O-Engpass, so dass Sie Millionen von Objekten in weniger als einer Sekunde auf jedem modernen Computer sortieren und filtern können.

Die eleganteste Art und Weise mit Sammlungen zu arbeiten, ist System.Linq Namespace in .NET 3,5

Danke - ich LINQ auch Objekte betrachtet, aber meine Sorge ist Verlust Flexibilität für typisierte Daten Vorlagen, die ich die Objekte in meiner Liste anzeigen muss.

Wenn Sie in diesem Moment nicht vorhersagen können, wie die Menschen sortieren und Ihre Objektsammlung filtern, dann sollten Sie bei System.Linq.Expressions Namespace schauen, um Ihre Lambda-Ausdrücke auf Nachfrage während der Laufzeit zu bauen (erst Sie Lassen Sie den Benutzer einen Ausdruck erstellen, dann kompilieren, ausführen und am Ende verwenden Sie den Reflexions-Namespace, um die Ergebnisse aufzuzählen. Es ist schwieriger, den Kopf herumzulegen, aber ein unschätzbares Feature, wahrscheinlich (für mich definitiv) noch bahnbrechender als LINQ selbst.

+0

lubos: Danke - Ich dachte auch über LINQ an Objekte, aber meine Bedenken dort ist der Verlust der Flexibilität für typisierte Datenvorlagen, die ich die Objekte in meiner Liste anzeigen muss. –

1

Ich bin noch nicht sehr vertraut mit WPF, aber ich sehe dies als eine Frage zum Sortieren und Filtern List<T> Sammlungen.

(withing mit manuell sortieren oder Filter implementieren)

Würden Sie überdenken Ihre eigene Art oder Filterfunktionen zu implementieren? Nach meiner Erfahrung ist es einfach zu bedienen. In den folgenden Beispielen wird ein anonymer Delegat verwendet. Sie können jedoch problemlos eine eigene Methode oder eine Klasse definieren, um eine komplexe Sortierung oder einen komplexen Filter zu implementieren. Eine solche Klasse könnte sogar Eigenschaften haben, die Sortierung und Filter dynamisch zu konfigurieren und zu ändern.

Verwenden List<T>.Sort(Comparison<T> comparison) mit benutzerdefinierten Funktion vergleichen:

// Sort according to the value of SomeAttribute 
List<MyCompositeObject> myList = ...; 
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b) 
{ 
    // return -1 if a < b 
    // return 0 if a == b 
    // return 1 if a > b 
    return a.SomeAttribute.CompareTo(b.SomeAttribute); 
}; 

Ein ähnlicher Ansatz für eine Unter Sammlung von Gegenständen aus der Liste zu bekommen.

Verwenden List<T>.FindAll(Predicate<T> match) mit Ihrer benutzerdefinierten Filterfunktion:

// Select all objects where myObjectType1 and myObjectType2 are not null 
myList.FindAll(delegate(MyCompositeObject a) 
{ 
    // return true to include 'a' in the sub-collection 
    return (a.myObjectType1 != null) && (a.myObjectType2 != null); 
} 
+0

Brian: Sobald MyCompositeObject erstellt ist, sortiere ich und sortiere kostenlos als Teil einer ICollectionView. Der Kern des Problems besteht darin, sich mit den separaten Objekttyp-Sammlungen zu befassen und sie als eine Sammlung zu behandeln. Zusammengesetzte Sammlungen sind die Antwort für die Erstellung der Sammlung, nicht aber die Sortierfilterung. –