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,您可以通过两种不同的方式实现此目的:

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 回答