7

そのため、WPF は CompositeCollections のビューに対する標準の並べ替えまたはフィルター処理の動作をサポートしていないため、この問題を解決するためのベスト プラクティスは何でしょうか。

異なるタイプのオブジェクト コレクションが 2 つ以上あります。それらを単一の並べ替え可能でフィルター可能なコレクションに結合したい (並べ替えまたはフィルターを手動で実装する必要はありません)。

私が検討したアプローチの 1 つは、コレクションをソートしたいプロパティや、各タイプのオブジェクト インスタンスなど、いくつかのコア プロパティのみを持つ新しいオブジェクト コレクションを作成することです。

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

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

これをよりエレガントな方法で行うための提案は何ですか?

4

3 に答える 3

1

更新:より洗練された解決策を見つけました:

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

リフレクションにより、Obj1 に格納されている特定の型が実行時に解決され、型固有の DataTemplate が期待どおりに適用されることがわかりました。

于 2008-08-23T03:48:11.093 に答える
1

あなたが言及する「ブルートフォース」メソッドは、実際には理想的なソリューションです。すべてのオブジェクトは RAM にあり、I/O のボトルネックがないため、最新のコンピューターでは数百万のオブジェクトを 1 秒もかからずに並べ替えおよびフィルター処理できます。

コレクションを操作する最も洗練された方法は、.NET 3.5 の System.Linq 名前空間です。

ありがとう - オブジェクトへの LINQ も検討しましたが、リストにオブジェクトを表示する必要がある型付きデータ テンプレートの柔軟性が失われることが懸念されます。

現時点で、人々がオブジェクト コレクションをどのようにソートおよびフィルター処理するかを予測できない場合は、System.Linq.Expressions名前空間を調べて、実行時に必要に応じてラムダ式を作成する必要があります (最初にユーザーに式を作成させ、次にコンパイルします)。 、実行し、最後にリフレクション名前空間を使用して結果を列挙します)。頭を抱え込むのはもっと難しいですが、非常に貴重な機能であり、おそらく (私にとっては断然) LINQ 自体よりも画期的な機能です。

于 2008-08-14T16:38:03.430 に答える
1

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

(並べ替えやフィルターを手動で実装する必要はありません)

独自のソート機能またはフィルター機能の実装を再考しますか? 私の経験では、使いやすいです。以下の例では匿名デリゲートを使用していますが、複雑な並べ替えやフィルターを実装する独自のメソッドやクラスを簡単に定義できます。このようなクラスには、並べ替えとフィルターを動的に構成および変更するためのプロパティを含めることもできます。

カスタム比較関数で使用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);
};

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

カスタム フィルター関数で使用List<T>.FindAll(Predicate<T> match)します。

// 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);
}
于 2008-08-14T18:37:22.613 に答える