Sortarea unei colecții compuse

Deci, wpf nu suportă comportamentul standard de sortare sau filtrare pentru vizualizările CompositeCollections, deci care ar fi cea mai bună practică pentru rezolvarea acestei probleme.

Există două sau mai multe colecții de obiecte de diferite tipuri. Doriți să le combinați într-o singură colecție separată și filtrabilă (cu necesitatea de a implementa manual sortarea sau filtrarea).

Una dintre abordările pe care le-am luat în considerare este să creez o colecție de obiecte noi, cu doar câteva proprietăți de bază, inclusiv cele pe care aș dori colectarea sortată și o instanță de obiect pentru fiecare tip.

class MyCompositeObject
{
    enum           ObjectType;
    DateTime       CreatedDate;
    string         SomeAttribute;
    myObjectType1  Obj1;
    myObjectType2  Obj2;
{
class MyCompositeObjects : List { }

Și apoi treceți prin cele două colecții de obiecte pentru a construi noua colecție compozită. Evident, aceasta este o metodă de forță brute, dar ar funcționa. Aș obține toate comportamentul implicit de sortare și filtrare a vederilor de pe noua mea colecție de obiecte compuse și aș fi capabil să pun un șablon de date pe acesta pentru a afișa articolele mele de listă în mod corespunzător, în funcție de tipul care este stocat efectiv în acel element compozit.

Ce sugestii există pentru a face acest lucru într-un mod mai elegant?

0
fr hi bn

3 răspunsuri

Actualizare: am găsit o soluție mult mai elegantă:

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

Am constatat că, datorită reflecției, tipul specific stocat în Obj1 este rezolvat în timpul rulării și tipul de date specificat este aplicat așa cum era de așteptat!

0
adăugat

I'm not yet very familiar with wpf but I see this as a question about sorting and filtering List collections.

(împreună cu necesitatea de a implementa manual sortarea sau filtrarea)

V-ați gândi la implementarea propriilor funcții de sortare sau filtrare? Din experiența mea este ușor de folosit. Exemplele de mai jos utilizează un delegat anonim, dar puteți defini cu ușurință propria metodă sau o clasă pentru a implementa un fel sau un filtru complex. O astfel de clasă ar putea avea chiar proprietăți pentru a configura și schimba sortarea și filtra dinamic.

Use List.Sort(Comparison comparison) with your custom compare function:

// Sort according to the value of SomeAttribute
List 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);
};

O abordare similară pentru obținerea unei sub-colecții de articole din listă.

Use List.FindAll(Predicate match) with your custom filter function:

// 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
adăugat
Brian: Odată ce MyCompositeObject este construit, mă sortează și se filtrează gratuit, ca parte a unei ICollectionView. Esența problemei se ocupă de colecțiile separate de tip de obiect și le tratează ca o singură colecție. Colecțiile compozite reprezintă răspunsul pentru crearea colecției, dar nu pentru filtrarea sortimentului.
adăugat autor Christopher Scott, sursa

"Forța bruta" pe care o menționați este soluția ideală. Ține minte că toate obiectele sunt în memorie RAM, nu există blocaj I/O, așa că poți să sortezi și să filtrezi milioane de obiecte în mai puțin de o secundă pe orice computer modern.

Cel mai elegant mod de a lucra cu colecțiile este spațiul de nume System.Linq din .NET 3.5

Mulțumesc - am considerat, de asemenea, LINQ pentru   obiecte, dar îngrijorarea mea este că există pierderi   de flexibilitate pentru datele tipizate   șabloane, pe care trebuie să le afișez   obiecte din lista mea.

Dacă nu puteți anticipa în acest moment modul în care oamenii vor sorta și filtra colecția dvs. de obiecte, atunci ar trebui să vă uitați la spațiul de nume System.Linq.Expressions pentru a construi expresiile lambda la cerere în timpul rulării (mai întâi lăsați utilizatorul pentru a construi expresie, apoi compilați, rulați și la sfârșit utilizați spațiul de reflecție pentru a enumera prin rezultate). Este mai dificil să vă înfășurați capul în jurul său, dar o caracteristică neprețuită, probabil (pentru mine, definitiv), chiar mai multă caracteristică de rupere decât LINQ însuși.

0
adăugat
lubos: Multumesc - Am considerat, de asemenea, LINQ la obiecte, dar preocuparea mea este pierderea de flexibilitate pentru șabloane de date tipizate, care trebuie să afișez obiectele din lista mea.
adăugat autor Christopher Scott, sursa