Применение where в ObservableCollection не влияет на сетку данных - PullRequest
0 голосов
/ 23 июня 2011

Я пытаюсь «отфильтровать» коллекцию 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>

recordObservableCollection обновляется нормально.

Но DataGrid не обновляется.

Ответы [ 3 ]

4 голосов
/ 23 июня 2011

Ваше поле или переменная с именем recordObservableCollection имеет одно значение изначально и другое значение после фильтрации.Поскольку вы дважды использовали new ObservableCollection<Record>(...), вы создали два отдельных наблюдаемых экземпляра коллекции.

Проблема в том, что DataGrid означает , все еще ссылаясь на первый экземпляр .Даже если вы изменили recordObservableCollection, это влияет только на его значение .Значение DataGrid.ItemsSource равно до того, что было до фильтрации .

Чтобы устранить эту проблему, необходимо повторно присвоить значение новой коллекции свойству ItemSource.Просто повторите то, что вы делали в первый раз, но после фильтрации:

dataGrid1.ItemsSource = recordObservableCollection;

и теперь ItemSource будет установлено новое значение recordObservableCollection.

0 голосов
/ 23 июня 2011

ObservableCollection получит обновление, потому что ObservableCollection (System.Collections.ObjectModel) генерирует событие каждый раз, когда коллекция изменяется, но вы должны снова установить коллекцию фильтров как itemsource, иначе не будет обновляться пользовательский интерфейс ...

Лучший способ сделать это - использовать открытое свойство, которое вы будете связывать в элементе управления как источник элемента, и в этом свойстве вы определите NotifyPropertyChanged в установщике. Каждый раз, когда вы будете изменять коллекцию с помощью этого свойства, элемент управления также будет обновляться ...

Предположим, у вас есть сетка данных в test.xaml

-> Сначала для всей работы с INotifyPropertyChanged добавьте абстрактный класс в свой проект, унаследуйте его от интерфейса INotifyPropertyChanged и определите метод 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 
  }

}

здесь и сейчас, если вы обновите свою коллекцию, используя свойство любого другого свойства, метод или команда. Пользовательский интерфейс будет обновлен, так как вы установили OnPropertyChanged ...

Теперь вернемся к test.xaml, здесь нужно сделать две вещи

  1. Установить dataContext для test.xaml либо в коде behing, либо в xaml (В коде сразу после InitializeComponent () создайте экземпляр класса viewmodel и назначьте его как DataContext следующим образом

      public test()
        {
        InitializeComponent();
    
        testViewModel  vm = new testViewModel();
        this.DataContext = vm;
        }
    
  2. Свяжите свойство, которое вы определили в testViewModel, с сеткой

     <Grid Name="MyGrid" DataContext="{Binding recordObservableCollection}">
      </Grid>  
    
0 голосов
/ 23 июня 2011

Экспонировать ObservableCollection<Record> как общедоступное свойство

также

Использование ObservableCollection влияет только на привязку, когда вы добавляете / удаляете элементы из списка.При использовании ObservableCollection вам не нужно сбрасывать привязку к списку или DataGrid, когда ваша коллекция изменилась (не изменился элемент внутри коллекции).Но они не имеют никакого эффекта при изменении свойств вашего объекта данных.Для этого вам необходимо реализовать INotifyPropertyChanged интерфейс для вашего DataObject.

...