在过滤时更改ListView中项的属性时出现问题

本文关键字:属性 问题 过滤 ListView | 更新日期: 2023-09-27 17:54:28

我有一个可以过滤的项目列表。Item类有一个IsChecked属性。有时,如果我在过滤列表时更改此属性(在运行时通过Checkbox),它不会更改源集合中的属性。我做错了吗?

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");
          }
     }
     ...
}

在过滤时更改ListView中项的属性时出现问题

我认为你的代码没有问题,让我解释一下:

执行该操作时:

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

你将IsChecked属性设置为true,仅适用于ListView当前显示的项目(即仅通过过滤器的项目)。

如果你想设置observablecollection_items中的所有元素为真或假,你可以通过两种不同的方式实现:

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应该工作正常,但因为它不是,这是一种绕过它的方法,直接与您的集合一起工作,但要考虑过滤的元素。


希望这有助于,问候!