Change property in Viewmodel

Topics: Questions
Dec 5, 2013 at 9:28 AM

I change a property in viewmodel which is mapped to model. If property is changed I send a message.
class ViewModelA
    public bool IsVisible
        get { return GetValue<bool>(IsVisibleProperty); }
        set { SetValue(IsVisibleProperty, value); }

    public static readonly PropertyData IsVisibleProperty = RegisterProperty("IsVisible", typeof(bool), null, (sender, e) => ((StationViewModel)sender).OnIsVisibleChanged());

    private void OnIsVisibleChanged()
        var message = new StationVisibilityMessage{ IsVisible = IsVisible, Station = Station};
        _messageMediator.SendMessage(message, StationVisibilityMessage.Tag);
My problem is that the property in viewmodel is changed imidiately. But the property in the model is changed after the message is sended.

Because the receiving viewmodel has reference to the models and needs the new information
class ViewModelB

        private void OnStationVisibilityChanged(StationVisibilityMessage message)
            if ( Machine != null && !message.IsVisible && ActiveStation == message.Station)
                 ActiveStation = Machine.Stations.FirstOrDefault(s => s.IsVisible);
                 // here the IsVisible has the old Value
Dec 6, 2013 at 9:09 AM
The reason for this is that you are the first to hook into the changed event. Under the hood, this happens:

1) Call the Changed event (which is provided in the RegisterProperty method, thus OnIsVisibleChanged)
2) Call changed event handlers (which the ViewToViewModel uses, because it maps the properties using the PropertyChanged event of the model)

We do this because we want to give the owner of the property the advantage of being called first (owner has a higher priority than the users). There are several workarounds:

1) Override OnPropertyChanged and call the base first. Then you can control whether the message is sent.
2) Create a "watcher" service that subscribes to PropertyChanged of the models that contain the IsVisible change.

I think option 1 is the best.
Dec 9, 2013 at 7:59 AM
Thanks for your answer.

Ok. I have a third option:

ActiveStation = Machine.Stations.FirstOrDefault(s => s.IsVisible && s != message.Station);

Take a station which is not visible, but also not the station which is send the message.