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

У меня есть ListView, привязанный к ObservableCollection...

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

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

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


person michael    schedule 27.04.2011    source источник


Ответы (3)


По умолчанию 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.

person myermian    schedule 27.04.2011
comment
Это сработало отлично, и спасибо за информацию о кастинге. - person michael; 27.04.2011

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

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

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


private void SortCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
{
  Debug.WriteLine( "Changed" );
}
person Muad'Dib    schedule 27.04.2011

ObservableCollection{T} предоставляет INotifyCollectionChanged.CollectionChanged< /а> событие. При привязке к ItemsSource механизм привязки данных обрабатывает распространение изменения из источника в элементы управления, но если вам нужно выполнить дополнительную обработку, вы можете прикрепить обработчик к событию 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;
person Oppositional    schedule 27.04.2011
comment
Это будет работать, если первоначальный автор хочет, чтобы логика была в ViewModel, но я предполагаю, что ему нужна дополнительная логика в представлении, поскольку он показал некоторый XAML и привязку. Хотя я могу ошибаться. - person myermian; 27.04.2011