views:

45

answers:

1

I'm using mvvm for my new project. I have a message dispatcher to send messages between viewmodels but in one case I have to receive messages in a view. This view contains a toolbar panel that must contain the toolbar related to detail view (example editing a customer needs a toolbar with Save, Undo, Redo, Cancel).

The problem is that I have to subscribe to messages inside the view to be able to write this:

broker.Subscribe<AddToolbarPanelMessage>(x=>toolbar.Add(x.Panel));

But... I have to 1) retrive the view from a container (so not XAML!) in order to have DI for the messageBroker 2) call a static IoC.Container.Resolve(); inside constructor

Option 2 broke VS2010 designer because container is not configured in design mode...

Any idea? View is not visible from viewmodel, I use a static ViewModelLocator.

A: 

In cases where I need to communicate from my ViewModel to my View I create an event in my ViewModel's interface, and I have my View handle that event. Your ViewModel could subscribe to your AddToolbarPanelMessage, then raise an event, which your view handles.

public interface ICustomerViewModel
{
    event EventHandler AddToolbarPanel;
}

public class CustomerViewModel : ViewModelBase, ICustomerViewModel
{
    public event EventHandler AddToolbarPanel;

    public CustomerViewModel(IMessenger broker) : base(broker)
    {
        broker.Subscribe<AddToolbarPanelMessage>(
        MessengerInstance.Register<AddToolbarMessage>(this, AddToolbarMessageReceived);
    }
    private void AddToolbarMessageReceived(AddToolbarMessage msg)
    {
        var eh = AddToolbarPanel;
        if (eh != null)
            eh.Invoke(this, EventArgs.Empty);
    }
}

You can easily handle the event in your view's ctor...

public partial class CustomerView : UserControl
{
    public CustomerView()
    {
        InitializeComponent();
        ((ICustomerViewModel)this.DataContext).AddToolbarPanel += CreateToolbarPanel;
    }
    private void CreateToolbarPanel(object sender, EventArgs e)
    {
        // do your stuff
    }
}
Matt Casto
Agreed - I don't think that the message infrastructure shoud be used in the view. Using interfaces and events makes a lot of sense to me.
Chris Koenig