在ObservableCollection上应用where;不要反思数据网格

本文关键字:数据 数据网 网格 ObservableCollection 应用 where | 更新日期: 2023-09-27 18:00:23

我尝试"过滤"ObservableCollection并更新绑定的DataGrid。

 ObservableCollection<Record> recordObservableCollection;
recordObservableCollection = new ObservableCollection<Record>(GetData()); //GetData() returns  IEnumerable<Record>
dataGrid1.ItemsSource = recordObservableCollection;

然后我尝试过滤这个集合:

 recordObservableCollection = new ObservableCollection<Record>(recordObservableCollection.Where(filter));//filter is Func<Data.Record, bool>

CCD_ 1被很好地更新。

但是DataGrid没有更新。

在ObservableCollection上应用where;不要反思数据网格

名为recordObservableCollection的字段或变量最初有一个值,过滤后有一个不同的值。因为您使用了两次new ObservableCollection<Record>(...),所以创建了两个独立的可观察集合实例。

问题是DataGrid仍然引用第一个实例。即使您已经更改了recordObservableCollection,这也只会影响值。DataGrid.ItemsSource的值仍然是过滤前的值

若要解决此问题,需要将新集合的值重新分配给ItemSource属性。只需重复第一次所做的操作,但在过滤后

dataGrid1.ItemsSource = recordObservableCollection;

并且现在CCD_ 8将被设置为CCD_。

ObservableCollection将得到更新,因为ObservableCollections(System.Collections.ObjectModel)每次更改集合时都会抛出一个事件,但您必须再次将筛选器集合设置为项源,否则它不会更新UI。。。

最好的方法是使用一个公共属性,您将在控件中绑定该属性作为项源,并在该属性中在setter中定义NotifyPropertyChanged。每次使用此属性更改集合时,控件也将更新。。。

假设您的数据网格位于test.xaml 中

-->对于INotifyPropertyChanged的所有工作,首先在项目中添加一个抽象类,从INotifyAttributeChanged接口继承它,并定义OnPropertyChanged方法

 public abstract class ViewModelBase : INotifyPropertyChanged
 {
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

-->在您的项目中添加一个名为testViewModel的类后,它将继承您的ViewModelBase类。。

-->现在在testViewModel中,您将为网格绑定创建一个属性,如

  Private ObservableCollection<Record> _recordObservableCollection
  public  ObservableCollection<Record> recordObservableCollection
  {
  get
  {
       if(_recordObservableCollection == null)
        {
         _recordObservableCollection = new ObservableCollection<Record>(GetData());
         recordObservableCollection = new ObservableCollection<Record>(recordObservableCollection.Where(filter));
        }
       return _recordObservableCollection;
  }
 Set
  {
     _recordObservableCollection = Value;
      OnPropertyChanged("recordObservableCollection"); //Your property name 
  }

}

现在,如果你在任何其他属性上使用属性更新你的集合,方法或命令UI将在setter中更新,因为你已经定义了OnPropertyChanged。。。

现在回到test.xaml这里你必须做两件事

  1. 在代码behing或xaml中设置test.xaml的dataContext(在InitializeComponent()之后的Code-behind中,创建viewmodel类的一个intance,并将其分配为DataContext,如下所示

      public test()
        {
        InitializeComponent();
        testViewModel  vm = new testViewModel();
        this.DataContext = vm;
        }
    
  2. 将您在testViewModel中定义的属性绑定到网格

     <Grid Name="MyGrid" DataContext="{Binding recordObservableCollection}">
      </Grid>  
    

recordObservableCollection0公开为公共属性

还有

使用ObservableCollection只会在添加/删除列表中的项目时影响绑定。通过使用ObservableCollection,当您的集合发生更改(而不是集合中的项目发生更改)时,您不需要重置与列表或DataGrid的绑定。但是,当数据对象属性发生更改时,它们不会产生任何影响。为此,您需要为DataObject实现INotifyPropertyChanged接口。