WPF: Как мне подключиться к уведомлению об изменении коллекции ItemsSource в ListView?

#wpf #listview #observablecollection #itemssource #inotifycollectionchanged

#wpf #listview #observablecollection #itemssource #inotifycollectionchanged

Вопрос:

У меня есть a, ListView который привязан к базе данных ObservableCollection

 <ListView x:Name="List1" ItemsSource="{Binding MyList}" />
  

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

В принципе, когда коллекция изменяется, я хочу выполнить дополнительную работу помимо того, что ListView уже выполняет при обновлении своего списка.

Ответ №1:

По умолчанию ItemsSource имеет тип IEnumerable . Сначала вам нужно привести к типу, который имеет доступ к CollectionChanged событию, затем добавить обработчик для этого события.

 ((INotifyCollectionChanged)List1.ItemsSource).CollectionChanged  =
    new NotifyCollectionChangedEventHandler(List1CollectionChanged);

public void List1CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
{
    // Your logic here
}
  


Примечание: В моем примере я привел его к INotifyCollectionChanged , но вы действительно можете привести его к любому объекту, который это реализует. Хотя, в качестве наилучшей практики, вы должны привести к наиболее общему типу, который дает вам доступ к нужным вам методам / свойствам / событиям. Итак, хотя вы можете преобразовать его в ObservableCollection , вам не нужно этого делать. INotifyCollectionChanged содержит нужное вам событие, и если вы когда-нибудь решите использовать какой-либо другой тип коллекции, который его реализует, это будет продолжать работать, тогда как приведение к ObservableCollection означает, что если вы однажды решите, что ваш список теперь имеет тип MyOwnTypeOfObservableCollectionNotDerivedFromObservableCollection , это сломается. 😉

P.S. Это должно быть в коде xaml.

Комментарии:

1. Это сработало отлично, и спасибо за информацию о приведении.

Ответ №2:

вам нужно будет прикрепить обработчик к вашему списку. Или используйте CollectionView и подключайте измененное событие туда.

в вашей части кода сделайте вот так:

 MyList.CollectionChanged  = new NotifyCollectionChangedEventHandler( this.MyCollectionChanged );


private void SortCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
{
  Debug.WriteLine( "Changed" );
}
  

Ответ №3:

ObservableCollection{T} предоставляет INotifyCollectionChanged.Событие изменения коллекции. При привязке к ItemsSource механизм привязки данных обрабатывает распространение изменений из источника в элемент управления items, но если вам нужно выполнить дополнительную обработку, вы можете прикрепить обработчик к событию CollectionChanged и использовать предоставляемые им NotifyCollectionChangedEventArgs.

Предполагая, что у вас есть общедоступное свойство в вашей модели представления с именем myList:

 public ObservableCollection<T> MyList
{
  get
  {
    if(_viewModelMyList == null)
    {
      _viewModelMyList = new ObservableCollection<T>;
      _viewModelMyList.CollectionChanged  = (o, e) => 
      {
        // code to process change event can go here
        if(e.Action == NotifyCollectionChangedAction.Add)
        {
        }
      };
    }
    return _viewModelMyList;
  }
}
private ObservableCollection<T> _viewModelMyList;
  

Комментарии:

1. Это сработало бы, если исходный постер хочет, чтобы логика была в ViewModel, но я предполагаю, что ему нужна дополнительная логика в View, поскольку он показал некоторый XAML и привязку. Хотя я могу ошибаться.