1

基本的に、2つのListViewがそれぞれ異なるにバインドされていますItemsSource

リスト1は変更できません(これはReadOnlyObservableCollection)です。
リスト2は(ユーザーの操作によって)変更できます。

リスト1にフィルターを追加して、リスト2にあるものが何も表示されないようにする必要があります。これは、これまでの私のコードです...

view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
    MyItem item = o as MyItem;
    return List2.ItemsSource.??;
};


List2.ItemsSourceは、ObservableCollection(実際の内容)ではなく、IEnumerableとして返されます。これをできるだけ効率的に実行したいので、次のようにする必要があるかどうかわかりませんでした。

  1. 明示的にItemsSourceをIListとしてキャストして、Containsにアクセスしますか?
  2. ItemsSourceを自分で繰り返して、アイテムが含まれているかどうかを確認しますか?
  3. LINQのCast拡張メソッドを使用してIList(または他のタイプ)にキャストし、Contains?にアクセスします。
  4. その他の方法で?

アップデート:

初めてレンダリングした後、アイテムのフィルタリングを続行していないようです。

view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
    MyItem item = (MyItem)o;
    var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
    //return collection.Contains(item);//Filters out ALL items from the list
    return !collection.Contains(item); //Shows all items, but as I add items
                                       //to list 2 it doesn't filter items out of
                                       //list 1.
};

更新2:

なぜフィルターを再適用しないのか理解できたと思います。元のコレクションはCollectionChanged通知を発生させないため、フィルターを再度実行する必要はありません。おそらく、この部分を解決することは、別の質問としてより適していますか?しかし、誰かがここでそれに答えたい場合は:

List2コレクションが変更されたときにList1にフィルターを再適用させるにはどうすればよいですか?

更新3:別のSO質問 でcollectionchangedイベントに関連付ける方法を尋ね、回答を得ました。

4

1 に答える 1

1

ItemsSourceは静的にとして宣言されIEnumerableますが、実際のランタイムタイプはを実装するものであれば何でもかまいませんIEnumerable。それが実際にであることがわかっている場合は、次のObservableCollection<MyItem>タイプにキャストできます。

view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
    MyItem item = (MyItem)o;
    var collection = (ObservableCollection<MyItem>)List2.ItemsSource;
    return collection.Contains(item);
};

(または、このインターフェイスで定義されているためIList<MyItem>、にキャストすることもできます)Contains

Linqも良いオプションです:

view = CollectionViewSource.GetDefaultView(List1.ItemsSource);
view.Filter += o =>
{
    MyItem item = (MyItem)o;
    return List2.ItemsSource.Cast<MyItem>().Contains(item);
};
于 2011-04-27T14:12:08.880 に答える