mvvm - PropertyChanged не обновляет графический интерфейс с изменением списка, но делает, если я назначаю новый список - C # silverlight - PullRequest
2 голосов
/ 10 декабря 2010

Моя ViewModel содержит List<string> SelectedActions и метод AddSelectedAction(string addMe)
Если у меня есть следующий код, GUI не обновляется при вызове метода:

SelectedActions.Add(addMe);
OnPropertyChanged("SelectedActions");

Но если я используютогда это работает:

SelectedActions.Add(addMe);
List<string> li = new List<string>();
foreach (string st in SelectedActions)
li.Add(st);
SelectedActions = li;
OnPropertyChanged("SelectedActions");

Где у меня есть следующая служебная функция

protected void OnPropertyChanged(string propertyName)
{
  this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

А также реализация INotifyPropertyChanged
Обратите внимание, что код, который я опубликовал, работаетесли я уберу вызов OnPropertyChanged, я знаю, что он хотя бы что-то делает

Ответы [ 4 ]

5 голосов
/ 10 декабря 2010

Это потому, что объект, которому дали SelectedActions, выполняет небольшую оптимизацию.Вы сказали, что свойство изменилось, но он сделал быстрый вызов Equals () и обнаружил, что это все тот же объект, поэтому он коротко обновил значение.Когда вы назначаете новый список для SelectedActions, то элемент управления видит, что это совершенно новый объект, и, следовательно, выполняет обновление.

Самое простое решение - использовать ObservableCollection, который реализует INotifyCollectionChanged, - интерфейс, разработанный для решения этой ситуации.

5 голосов
/ 10 декабря 2010

Я бы рекомендовал изменить List<string> на ObservableCollection<string>. Это стандартный / рекомендуемый способ хранения коллекций, о котором необходимо уведомлять, когда они были обновлены / изменены.

Это обработает все уведомления об изменениях для вас, и вам не нужно будет явно звонить OnPropertyChange()

2 голосов
/ 10 декабря 2010

Я бы предположил, что здесь вам нужна коллекция ObservableCollection, а не список. Я не уверен, какой интерфейс вы ожидаете увидеть обновленным, но добавление объекта в список не меняет сам список, поэтому пользовательский интерфейс не увидит, что есть что обновить.

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

Если при добавлении или удалении элементов из вашей коллекции необходимо выполнить другие действия, ObservableCollection поддерживает событие CollectionChanged, которое вызывается при добавлении или удалении объекта из списка. По умолчанию это событие также запускает событие NotifyPropertyChanged для обновления вашего пользовательского интерфейса, поэтому вам не нужно добавлять его вручную.

1 голос
/ 10 декабря 2010

Вам нужно ObservableCollection<T> для того, что вы пытаетесь достичь. Список не вызывает никаких событий, когда элементы добавляются или удаляются, поэтому пользовательский интерфейс не может знать, что его нужно обновить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...