2008-08-14 14 views
6

WPFでは、CompositeCollectionのビューの標準的な並べ替えやフィルタリングの動作がサポートされていないため、この問題を解決するためのベストプラクティスは何でしょうか。複合コレクションのソート

異なるタイプのオブジェクトコレクションが2つ以上あります。それらを1つのソート可能でフィルタリング可能なコレクションにまとめたい(ソートまたはフィルタを手動で実装する必要があります)。

私が考えてきた手法の1つは、コレクションをソートする必要があるオブジェクトや各タイプのオブジェクトインスタンスなど、いくつかのコアプロパティを持つ新しいオブジェクトコレクションを作成することです。

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

次に、2つのオブジェクトコレクションをループして新しい複合コレクションを構築します。明らかに、これはやや強引な方法ですが、うまくいくでしょう。私は、新しいコンポジットオブジェクトコレクションのデフォルトのビューソートとフィルタリングの動作をすべて取得し、そのコンポジットアイテムに実際に格納されているタイプに応じて、リストアイテムを適切に表示するためにデータテンプレートを配置できます。

これをより洗練された方法で行うにはどのような方法がありますか?

答えて

1

更新:カスタムフィルタ機能付き

使用List<T>.FindAll(Predicate<T> match)私は反射による、Obj1とに格納されている特定のタイプがあることがわかっ

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

:私ははるかにエレガントな解決策を見つけました実行時に解決され、型固有のDataTemplateが期待通りに適用されます。

1

「ブルートフォース」の方法は、実際には理想的なソリューションです。すべてのオブジェクトがRAMにあり、I/Oのボトルネックがないので、現代のコンピュータで何百万ものオブジェクトを1秒未満で大量に並べ替えてフィルタリングすることができます。

のコレクションで作業するための最もエレガントな方法は、.NET 3.5でSystem.Linqの名前空間です

おかげで - 私はまた オブジェクトにLINQと考えられますが、私の懸念は、型指定されたデータのための柔軟性の 損失がある テンプレート、私は オブジェクトを私のリストに表示する必要があります。

あなたは、あなたが最初の(そして、あなたは実行時にオンデマンドであなたのラムダ式を構築するためにSystem.Linq.Expressions名前空間を見なければならない、人々があなたのオブジェクトのコレクションを並べ替え、フィルタしますどのようにこの時点で予測することができない場合式を作成し、コンパイルして実行し、最後にリフレクション名前空間を使用して結果を列挙します)。それはあなたの頭をラップするのは難しいですが、LINQ自体よりもはるかに画期的な機能を(おそらく(私にとっては確かに))非常に貴重な機能です。

+0

lubos:ありがとうございました - 私もオブジェクトにLINQを考慮しましたが、私のリストにオブジェクトを表示する必要があります型付きのデータテンプレートの柔軟性の損失があります。 –

1

私はまだWPFに慣れていませんが、これはコレクションの並べ替えとフィルタリングに関する質問として参照してください。List<T>

独自のソートやフィルタ機能を実現見直すだろう

(手動ソートやフィルタを実装する必要がwithing)?私の経験では使いやすいです。以下の例では、匿名の代理人を使用していますが、複雑なソートやフィルターを実装する独自のメソッドやクラスを簡単に定義できます。このようなクラスには、並べ替えとフィルタを動的に設定および変更するためのプロパティーがあります。カスタムと

使用List<T>.Sort(Comparison<T> comparison)コンペア機能:

// 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); 
}; 

リストから項目のサブコレクションを取得するための同様のアプローチを。

// 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

ブライアン:MyCompositeObjectがビルドされると、ICollectionViewの一部として空きのソートとフィルタリングが行われます。この問題の重大な点は、別々のオブジェクト型コレクションを扱い、それらを1つのコレクションとして扱うことです。コンポジット・コレクションは、コレクションの作成には役立ちますが、ソート・フィルターは使用できません。 –

関連する問題