#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 и привязку. Хотя я могу ошибаться.