Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have been looking at a couple of different approaches on how I can notify the UI about messages coming from the ViewModel, and wanted to see if this seemed appropriate or if it is too coupled. (We already have a static class that deals with notifications that I am trying to wrap for now, and maybe remove at a later time?)

INotifier
{
  void Notify(Notification notification);
}

ConcreteNotifier()
{
  void Notify(Notification notification)
  {
    Notification.ShowMessage(notification.Title, notification.Message, notification.MessageLevel);
  }
}

Main will create ConcreteNotifier and pass it into each View, which will pass it into each VM

ViewModel(INotifier notifier)
{
  _notifier = notifier;
}

DoStuff()
{
  try
  {
  }
  catch(Exception ex)
  {
    _notifier.Notify(new Notification{Title="DoStuff Error", Message=ex.Message, MessageLevel=Error});
  }
}

This seems ok to me, however there is coupling due to the Notification class. This is really just encapsulating parameters, so it is probably ok, but I wanted to run it past some people who are more familiar with MVVM and UI interaction. I only need to talk one way, so the Messenger pattern seems like overkill as I do not need to talk to other VM's, and this seemed like a simplistic way of dealing with this issue. Can anybody verify that this approach is ok, or if it has some issues with it?

share|improve this question

2 Answers 2

Generally speaking, view should bind to viewmodel and viewmodel should notify view through injected adapter. I read about this approach in Mark Seemann's "Dependency injection in .NET" book.

You are injecting, to your viewmodels, interface like this:

public interface IWindow
    {
        void Close();

        IWindow CreateChild(object viewModel);

        void Show();

        bool? ShowDialog();
    }

Download source code to see usage: http://www.manning.com/seemann/

Another approach, through static Messager, is proposed by mvvm light framework. Here are some tutorials and videos: http://www.galasoft.ch/mvvm/#tutorials

Personally I prefer injection, because only stateless classes should be considered as static (otherwise there are not testable). Besides, static Messager hides class dependency.

share|improve this answer
1  
I am fine with injection, and make heavy use of it. However, my only concern with that would be that should the ViewModel really care about UI concerns, like Show and ShowDialog? –  Justin Pihony Oct 1 '12 at 17:29
    
I don't want to misguide you because I'm not an expert. My only advice is to analyze WpfProductManagementClient project from Seemann's book source code. However, I'm using this pattern in my regular project at work and it works fine. I like this IWindow interface even more because I'm hosting WPF in WinForms. Using it I can flexibly switch between WinForms and Wpf implementations. –  Kuba Oct 1 '12 at 18:35

If you are looking for a general approach for notifications (I imagine something along the lines of a "notification tray", so corrent me if I'm wrong), this is, how I do it:

The notification is always realyed through the Messenger class from one ViewModel to another. The ViewModel of the component sending the notification creates the message based on its properties and command executions by the view. The recieving ViewModel then exposes the message properties or the whole message on its properties. Those get propagated via binding into the View.

All notification of UI should be, if possible, done via binding, which will minimize to the amout of codebehind needed. Furthermore, the ViewModel should be the decision maker and "publisher" of notifications. This way, you create a derived message class (You didn't which MVVM library you use) which can be recieved at multiple notification targets, which will give you great flexibility in sending and recieving notifications.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.