Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open dialog in WPF MVVM

Tags:

mvvm

dialog

wpf

I have an application that need to open a dialog from a button where the user enters some information.

At the moment I do it like this (which works fine)

  • The button click generates a command in the ViewModel.
  • The ViewModel raises an event which the Controller listens to.
  • The Controller works out the details of the new window (i.e. View, ViewModel & model) and opens it (ShowDialog)
  • When the window is closed the Controller adds the result to the eventargs and returns to the ViewModel
  • The ViewModel passes the information to the Model.

There are a lot of steps but they all make sense and there is not much typing.

The code looks like this (the window asks for the user's name)

ViewModel:

AskUserNameCommand = DelegateCommand(AskUserNameExecute);
...

public event EventHandler<AskUserEventArgs> AskUserName;

void AskUserNameExecute(object arg) {
    var e = new AskUserNameEventArgs();
    AskUserName(this, e);
    mModel.SetUserName(e.UserName);
}

Controller:

mViewModel.AskUserName += (sender,e) => {
    var view = container.Resolve<IAskUserNameView>();
    var model = container.Resolve<IAskUserNameModel>();
    var viewmodel = container.Resolve<IAskUserNameViewModel>(view, model);
    if (dlg.ShowDialog() ?? false)
        e.UserName = model.UserName;
}

My question is how the horizontal communication works in the MVVM pattern. Somehow it seems wrong to let the controller be involved in the data transfer between the models.

I have looked at the mediator pattern to let the models communicate directly. Don't like that idea since it makes the model depending on implemetations details of the GUI. (i.e. if the dialog is replaced with a textbox, the model need to change)

like image 916
adrianm Avatar asked Nov 26 '09 21:11

adrianm


1 Answers

I don't like most of the current suggestions for one reason or another, so I thought I would link to a nearly identical question with answers I do like:

Open File Dialog MVVM

Specifically the answer by Cameron MacFarland is exactly what I do. A service provided via an interface to provide IO and/or user interaction is the way to go here, for the following reasons:

  • It is testable
  • It abstracts away the implementation of any dialogs so that your strategy for handling these types of things can be changed without affecting constituent code
  • Does not rely on any communication patterns. A lot of suggestions you see out there rely on a mediator, like the Event Aggregator. These solutions rely on implementing two-way communication with partners on the other side of the mediator, which is both hard to implement and a very loose contract.
  • ViewModels remain autonomous. I, like you, don't feel right given communication between the controller and the ViewModel. The ViewModel should remain autonomous if for no other reason that this eases testability.

Hope this helps.

like image 131
Anderson Imes Avatar answered Sep 17 '22 17:09

Anderson Imes