ObservableCollection теряет привязку, когда я "новый" это
У меня есть ListBox на моем пользовательском интерфейсе, который связан с свойством ObservableCollection. Я установил новый экземпляр ObservableCollection в свойство в конструкторе модели представления, и я могу добавить элементы к нему с помощью кнопки в форме. Они видны в списке.
Все хорошо.
Однако, если я повторно инициализую свойство с новым в обратном вызове кнопки, он разбивает привязку, и пользовательский интерфейс больше не показывает то, что находится в коллекции.
Я предположил, что привязка будет продолжать искать значения свойства, но, по-видимому, связана с ссылкой, которая уничтожается новым.
Есть ли у меня это право? Может ли кто-нибудь расширить, как это связано? Есть ли способ переподтвердить его, когда моя модель представления не знает представления?
Ответы
Ответ 1
Убедитесь, что вы поднимаете PropertyChangedEvent после повторной инициализации своей коллекции. Повышение этого события позволит виду обрабатывать изменения в свойстве с моделью, не имеющей представления о представлении.
class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<string> _list = new ObservableCollection<string>();
public ObservableCollection<string> List
{
get { return _list; }
set
{
_list = value;
NotifyPropertyChanged("List");
}
}
public Model()
{
List.Add("why");
List.Add("not");
List.Add("these?");
}
}
Ответ 2
Я думаю, что на основе вашего описания, что вам нужно сделать, это реорганизовать свойство, которое предоставляет ваш ObservableCollection, чтобы оно вызывало событие PropertyChanged и когда ему присваивается новое значение. Пример:
public ObservableCollection<int> Integers
{
get { return this.integers; }
set {
if (this.integers != value)
{
this.integers = value;
RaisePropertyChanged("Integers");
}
}
}
Ответ 3
Предположим, что вы внедрили INotifyPropertyChanged в ViewModel, вы можете поднять событие изменения свойства на свой ObservableCollection всякий раз, когда вы назначаете ему новое значение.
public ObservableCollection<string> MyList { get; set; }
public void SomeMethod()
{
MyList = new ObservableCollection<string>();
RaisePropertyChanged("MyList");
}
Ответ 4
Обновления для ObservableCollection
обрабатываются путем подключения к событию CollectionChanged
, поэтому, когда вы создаете новый ObservableCollection
, ваш наблюдатель все еще смотрит на старую коллекцию.
Два простых предложения заключались бы в том, чтобы реализовать INotifyPropertyChanged
в классе, который содержит ObservableCollection
, и вызывать событие PropertyChanged
в настройщике свойства коллекции (не забудьте отцепить от старого сначала ваш наблюдатель, если это ваш собственный код).
private ObservableCollection<string> _myCollection = new ObservableCollection<string>();
public ObservableCollection<string> MyCollection
{
get { return _myCollection; }
set
{
if(_myCollection == value)
return;
_myCollection = value;
RaisePropertyChanged("MyCollection");
}
}
Вторым, и вариант, который я обычно предпочитаю, - это просто очистить и повторно заполнить коллекцию новыми данными, когда они появятся.
public void HandleCollectionData(IEnumerable<string> incomingData)
{
MyCollection.Clear();
foreach(var item in incomingData)
{
MyCollection.Add(item);
}
}