2
votes

I have a ViewModel that can create another ViewModel.

I want to set this ViewModel as the data context of existing View, then Navigate to that View.

In MyViewModel

private void CreateNewOrder()
{
    var order = new OrderViewModel(new Order(){/* setup some things */});
    // another ViewModel subscribes to MyCustomEvent
    this.eventAggregator.GetEvent<MyCustomEvent>().publish(order); 
    this.regionManager.RequestNavigate("DetailRegion", new Uri("OrderView", UriKind.Relative));
}

The problem is ...

  • My ViewModel needs reference to the region's name, and the View's name.
  • "DetailRegion" must contain the "OrderView" object.
  • DetailView.DataContext is set to OrderViewModel (using aggregate event subscription)

Is this tight coupling?

I've spent sometime looking in the Prism Quickstart project and found the "Controller" or something that is too complicated.

I just want to simplify decoupling View-ViewModel.

1
MVC isn't that complicated. I'd stick with the Quickstart thing that you found.McGarnagle

1 Answers

9
votes

The code you have added to the ViewModel, belongs in a controller.

  • ViewModels are dumb containers that hold a certain shape of data. They do not know where the data comes from or where it is displayed.
  • Views display a certain shape of data via bindings to a view model. They do not know where the data comes from, only how to display it.
  • Models hold real data. They do not know where is is consumed.

So what's missing from this picture? - Controllers publish and listen for events and fetch data for the ViewModel from a Model. They also control navigation.

It really should have been designed as MVCVM. I see no end of misuse of MVVM through the absence of controller classes. Give the Prism Quickstart another go.

Just to clarify how a controller fits into the MVVM picture, here is an example scenario:

  • Controller is registered and initialized by the module or app*.
  • Controller subscribes to a "show details" message.
  • Controller receives a "show details" message.
  • Controller constructs a "details" VM, fills it with data and assigns any ICommand properties to code in the controller (e.g. pretty much all app logic is in controllers).
  • Controller triggers display of the appropriate view, supplying the VM.
  • View data is bound to VM. Buttons are bound to ICommands in the VM.
  • User edits data and clicks submit. The submit code is in the Controller and decides what to do with the new data in the VM.

*Note: VMs and views do not need to hang around waiting for messages, so only controllers actually need to exist for the lifetime of the app (i.e. very small footprint). This is great for mobile apps and generally a good thing for any app.