How can I report that the property of an element in the observed collection has changed?

Ok, I have an ItemControl in a XAML file that binds to an ObservableCollection. The ObservableCollection is in the view model class (let this ViewModelA class be called), and each element in the ObservableCollection is an instance of another view model class (let it call the ViewModelB class).

ViewModelA has a property that, when changed, indirectly changes the values โ€‹โ€‹of properties found in many instances of the ViewModelB class. In other words, it does not go directly to ViewModelB and does not set its properties, thereby calling INotifyPropertyChange, but rather goes to the model, sets some property in my model, and this change in my model affects what ViewModelB should show.

How can I notify the opinion that something in ViewModelB has changed?

+4
source share
4 answers

You should be able to tell View that the collection has changed, and, in turn, call it to re-link to the entire collection (which will update the view).

If your model implements INotifyPropertyChanged , another option would be to have your ViewModelB class listen for changes on it, wrap the model, and change properties if necessary by changing events.

+2
source

Ideally, you could do as Reid Copsi shows in the picture ... Implement INotifyPropertyChanged on the model and listen to the ViewModelB for these events. Then ViewModelB will receive the changes no matter where the update occurs.

However, in some cases, the model does not implement (or cannot) INotifyPropertyChanged. In this case, you might consider using an event aggregator template to send a message between ViewModelA and instances of ViewModelB.

In this case, you can post the message "model changed" from ViewModelA. ViewModelB instances will be subscribed to this message, and each of them will be notified when A publishes the message. Then ViewModelB can raise the corresponding PropertyChanged events to tell the user interface what has changed.

More information on the event aggregator can be found in many frameworks, including

+1
source

To solve this problem, I created a VeryObservableCollection class. For each added object, it catches the NotifyPropertyChanged event of the object to the handler that fires the CollectionChanged event. For each deleted object, it removes a handler. Very simple and will give you exactly what you want. Partial Code:

 public class VeryObservableCollection<T> : ObservableCollection<T> /// <summary> /// Override for setting item /// </summary> /// <param name="index">Index</param> /// <param name="item">Item</param> protected override void SetItem(int index, T item) { try { INotifyPropertyChanged propOld = Items[index] as INotifyPropertyChanged; if (propOld != null) propOld.PropertyChanged -= new PropertyChangedEventHandler(Affecting_PropertyChanged); } catch (Exception ex) { Exception ex2 = ex.InnerException; } INotifyPropertyChanged propNew = item as INotifyPropertyChanged; if (propNew != null) propNew.PropertyChanged += new PropertyChangedEventHandler(Affecting_PropertyChanged); base.SetItem(index, item); } 
0
source

If a change in models changes in some properties of ViewModelB, and these properties have a change notification for the user interface (that is, ViewModleB implements INotifyPropertyChanged), this change will immediately be reflected in the user interface.

So, if you have an ObservableCollection of another viewmodelB, you do not need to hook events for the property changed by this viewmodelB. In my opinion, whoever changes the properties of viewmodelB (model class or anyone else), and if the properties are notified of the change, the view will be updated automatically.

0
source

All Articles