2012-03-07 4 views
0

У меня есть модель, состоящая из трех классов: A, B и C. A имеет ObservableCollection of B, B имеет ObservableCollection C. C имеет ссылку (не наблюдаемая .. Я не думаю, что это необходимо) для его родителя (B), а B имеет ссылку на A. Каждый атрибут A, B и C уведомляет об изменениях.Нотифицированное свойство не «обновлено» в пользовательском интерфейсе

У меня тогда есть класс модели, который «отслеживает» все выделенные объекты. Таким образом, он имеет ObservableCollection из A, B и C (единственное, что требуется для As, я сохраняю списки для B и C только для более быстрой ссылки).

У меня есть пользовательский элемент управления: он имеет ViewModel. В представлении есть список. Его ItemSources привязана к ViewModel к наблюдаемым коллекциям именованных датчиков. Этот ObservableCollection имеет RowViewModel. Каждый RowViewModel сохраняет ссылку на объект C.

Мое приложение загружает модель (создание A, B, объекты C), а затем задает список вида путем вызова этого метода (может быть, это проблема?)

public void setSensors(IList<C> list) 
     { 
      this.sensors.Clear(); 
      if (list != null) 
      { 
       foreach (var row in list) 
        this.sensors.Add(new RowViewModel(row)); 
      } 
     } 

Проблема заключается в том, что если Я изменяю свойство моего объекта C, это не отражается на пользовательском интерфейсе.

Кто-нибудь может мне помочь? Спасибо

Francesco

EDIT: (решаемые) благодаря вашим ответам я проверил мой код и изменил одну вещь: вместо того, чтобы связывать мой элемент пользовательского интерфейса для его ViewModel (и ViewModel просто «перенаправить» вызов к свойству модели), я напрямую привязываю интерфейс к реальному свойству, и он работает !! Итак ... в MVVM Я не могу использовать «ярлыки» ?? .. или если я их использую, я должен зарегистрироваться для уведомления об этом свойстве и «распространять» их?

+0

Вы изменили настройки вашего правительства? – squelos

+0

хорошо .. думаю думаю. Я поставил точку останова в своем «NotifyPropertyChanged», и он вводит его. – Francesco

+0

попробуйте проверить, слушает ли кто-то эти события. Если правильные объекты эффективно прослушивают, ну, я не знаю:/ – squelos

ответ

1

Я думаю, что ваш пользовательский интерфейс не обновлен, потому что он привязан к объекту RowViewModel, а не к C. Итак, вы должны подписаться на PropertyChanged событие C в своем конструкторе RowViewModel и сообщить об этих изменениях через RowViewModel.PropertyChanged. Кстати, можете ли вы привести пример привязки в пользовательском интерфейсе?

ОБНОВЛЕНО:

Примером "проксирование" PropertyChanged события:

public class Model: INotifyPropertyChanged 
{ 
    private string _YourProperty; 
    public string YourProperty 
    { 
    get { return _YourProperty; } 
    set 
    { 
     if (_YourProperty == value) return; 
     _YourProperty = value; 
     RaisePropertyChanged("YourProperty"); 
    } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
    if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class ViewModel: INotifyPropertyChanged 
{ 
    private Model _Model; 

    public ViewModel(Model model) 
    { 
    _Model = model; 
    _Model.PropertyChanged += OnModelPropertyChanged; 
    } 

    public string YourProperty 
    { 
    get { return _Model.YourProperty; } 
    } 

    private void OnModelPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
    if (e.PropertyName == "YourProperty") 
     RaisePropertyChanged("YourProperty"); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
    if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Вы можете прочитать также http://george.softumus.com/2011/10/inotifypropertychanged-and-magic.html - как избежать с помощью "волшебных строк" (жестко закодированные константы) в качестве имен свойств.

+0

У меня нет репутации, чтобы добавить ответ .. так что ... Пользовательский интерфейс My Row выполнен таким образом: свойство isOnline находится в RowViewModel: public Boolean isOnline { Получить { return myC.baisOnline; } } Мои сомнения ... b и свойства не являются "наблюдаемыми", но онлайн да. – Francesco

+0

Я не вижу необходимости проксировать событие изменения свойств во всех объявлениях, когда ваша собственность задана в конструкторе. И это не меняется. Это не обязательно, на самом деле это более вредно, вы обновляете модель модели представления каждый раз, когда свойство модели меняется, это заставит Silverlight обновить все без причины. –

+0

ОК, очень простой пример - у вас есть модель с двумя свойствами, такими как «Имя» и «Версия», и вы хотите увидеть ее в своем представлении как « [v. ] '(например,' SuperTool [v.2] '). Свойство Proxying - это простой способ сделать это (в WPF вы можете использовать 'IMultiValueConverter', но у Silvelight его нет). И на самом деле есть много других примеров, когда вы хотите использовать проксирование. Конечно, почти всегда вы можете использовать другую технику. Но очень спорный вопрос - лучший способ в каждом конкретном сценарии. Поэтому лучше знать, что проксирование существует, и это ваш собственный выбор - используйте это или нет. – chopikadze

1

Правила Модель для обновления пользовательского интерфейса Автоматически: -

  1. Ваше свойство типа коллекции должно быть типа ObservableCollection
  2. Ваша модель должна реализовать INotifyPropertyChanged интерфейс
  3. Каждое свойство вашей модели, если это не строка или тип значения, должны иметь тип, который должен реализовывать INotifyPropertyChanged
  4. Если ваше значение Свойство типа Collection изменяется, оно должно сгенерировать свойство PropertyChanged для имени свойства, даже если оно получено из ObservableColle ction
+0

Я думаю, что я следовал этим правилам ... – Francesco

+0

Скорее всего, за 4-м правилом не следуют люди, потому что они предполагают, что изменение экземпляра коллекции аналогично добавлению/удалению элемента в коллекции, в противном случае вам придется проверять наличие предупреждений о связях в VS Окно вывода. –

Смежные вопросы