Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm in MVVM ViewModel hell

So far, I am really happy with the way things have gone in my app's transition from typical click event handlers everywhere, to complete GUI decoupling. Now I'm running into something I can't quite figure out, and it's related to a window that I want my GUI to pop up, and it needs to display information from the model.

I guess the short version of my question is, is it absolutely forbidden in MVVM to allow the model to have a reference to a ViewModel? Here's my scenario: I have a bank of LEDs that cycles through RGB values very quickly. I would like a window in my GUI to display the updated colors via databinding with a ViewModel. I have the Window + UserControl working fine with a mockup ViewModel in a test application, but now I have to put this Window into my real application.

The particular mode I'm running in one that simulates what the hardware is doing. When I command the model to cycle through the colors, it starts a thread that changes the necessary class member variables' values.

My current implementation of MVVM is basically polling all of the time. To get other LEDs to update elsewhere, I have a thread running that calls a function in the ViewModel. This updates the properties, and so the GUI automatically updates since I'm using databinding. The problem in my LED example is that simulating the color sequence is done in a thread, so if I need to have a ViewModel poll for values, it will likely be slow due to excessive locking of the LED variables.

Therefore, I'm hoping that someone can recommend another approach to this problem. So far, the only thing I could really think of is to have the Window datacontext be an LEDViewModel, and then also pass the LEDViewModel to the Model. Then when I call the RGB cycling function, it can change the necessary ViewModel properties as necessary, and I won't need to use any locking at all.

Does this make sense? Any advice would be really appreciated.

like image 541
Dave Avatar asked Jan 20 '10 21:01

Dave


2 Answers

Have you tried just implementing the INotifyPropertyChanged interface on your model?

It would seem to me that this should perform well enough. When the color state changes on your model, you can fire off the PropertyChanged event, update the view model state from that notification, and have the view update via a binding on the view model.

like image 77
codekaizen Avatar answered Nov 08 '22 21:11

codekaizen


Why not use eventing on some sort of message broker for your application?

The easiest way to do this would be to use the Messenger in MVVMFoundation: http://mvvmfoundation.codeplex.com/

An example of this would be:

public class MyHardwareModel
{
     private void OnHardwareLEDChanged() // or whatever
     {
          SharedMessages.Messenger.NotifyColleagues(SharedMessages.LEDCHANGED);
     }
}

And then in your view model, when it spins up, you register for notification of these messages while that instance of the view model is alive:

public class MyHardwareViewModel
{
     public MyHardwareViewModel()
     {
          SharedMessages.Messenger.Register(SharedMessages.LEDCHANGED, UpdateLeds);
     }

     private void UpdateLeds()
     {
          //Update ObservableCollection here.
     }
}

The message mediator/broker pattern is really useful in these situations for so much more than just this. The Messenger built into MVVMFoundation is pretty powerful... in my sample I'm using pretty generic messages, but you can sent more typed messages with parameters.

There is a similar function built into Prism / Composite Application Guidance if you are using that called the EventAggregator. It's used in a similar way.

Hope this helps.

like image 3
Anderson Imes Avatar answered Nov 08 '22 21:11

Anderson Imes