2

フィルタリングできるアイテムのリストがあります。Item クラスにはプロパティ IsChecked があります。リストがフィルター処理されている間にこのプロパティを (チェックボックスを介して実行時に) 変更すると、ソース コレクションで変更されないことがあります。私はそれを間違っていますか?

public class ViewModel 
{
     private ObservableCollection<Item> _items;
     public ListCollectionView ItemsView { get; private set; }
     private bool _checkAll;

     public bool CheckAll
     {
          get
          {
               return _checkAll;
          }
          set
          {
               if (_checkAll == value)
                    return;

               _checkAll = value;

               if (_checkAll)
               {
                    foreach (Item i in ItemsView )
                         i.IsChecked = true;
               }
               else
               {
                    foreach (Item i in ItemsView )
                         i.IsChecked = false;
               }

               OnPropertyChanged("CheckAll");
          }
     }

     public ViewModel()
     {
          _items= new ObservableCollection<Item>(this.createList());
          ItemsView = CollectionViewSource.GetDefaultView(_items) as ListCollectionView;
          ItemsView.Filter = filter;
     }

     private void filter(object obj)
     {
          ...
     }

}

public class Item
{
     private bool _isChecked;

     public Item()
     {
     }

     public bool IsChecked
     {
          get {return _isChecked; }
          set
          {
               if (_isChecked == value)
                    return;
               _isChecked = value;
               OnPropertyChanged("IsChecked");
          }
     }

     ...
}
4

1 に答える 1

0

あなたのコードには何も問題はないと思います。説明させてください:

この操作を実行すると、次のようになります。

foreach (Item i in ItemsView )
     i.IsChecked = true;

ListView が現在表示している項目 (つまり、フィルターを通過した項目のみ) に対してのみ IsChecked プロパティを true に設定しています。

ObservableCollection _items のすべての要素を true または false に設定する場合は、次の 2 つの方法で実現できます。

foreach (Item i in _items) //enumerate the private ObservableCollection
     i.IsChecked = true;

また

foreach (Item i in ItemsView.SourceCollection) //enumerate the underlying ObservableCollection
     i.IsChecked = true;

Item クラスが INotifyPropertyChanged を実装する場合、UI は問題なく変更を反映するはずです。


編集1(以下の議論に基づく):

アイテムをチェック/チェック解除する別の方法は次のとおりです。

public bool CheckAll
 {
      get { return _checkAll; }
      set
      {
           if (_checkAll == value)
                return;

           _checkAll = value;

           _items.Where(ItemsView.Filter.Invoke).Select(i=>i.IsChecked=_checkAll);

           OnPropertyChanged("CheckAll");
      }
 }

ListView の列挙は正常に機能するはずですが、これはそうではないため、コレクションを直接操作しますが、フィルター処理された要素を考慮に入れます。


これがお役に立てば幸いです。

于 2013-01-18T19:02:12.293 に答える