John McArthur
John McArthur

Reputation: 1024

WPF MVVM Opening one View from another

I am just getting started with WPF + MVVM. I think I’ve got the hang of the basics. However, I have a question (hopefully not a stupid one).

I have a View showing a list of customers. I want to edit one of these customers. How do I load the edit view with its separate ViewModel from the List ViewModel.

I’m sure this is a fairly standard scenario, with a fairly straightforward answer, but I’ve spent a chunk of time googling and come up with nothing concrete. Can someone point me in the direction of a straightforward example?

If I’m wrong and it’s not straightforward, what is the best way to do this type of thing?

Upvotes: 2

Views: 2894

Answers (1)

stijn
stijn

Reputation: 35901

A common way of doing this (not only in MVVM but it applies well) is to give your list VM access to a so-called service. This service then implements creating and showing the editor (for which it probably uses yet another service).

Example:

/// Always use an interface for the service: it will make it a breeze
/// to test your VM as it decouples it from the actual service implmentation(s)
interface ICustomerEditorService
{
  /// Do whatever needed to get the user to edit the Customer passed in,
  /// and return the updated one or null if nothing changed.
  /// Customer here is likeyly your customer model, or whatever is neede
  /// to represent the editable data
  Customer EditCustomer( Customer toEdit );
}

class ListViewModel
{
  /// service gets passed to constructor, you can use dependency injection
  /// like MEF to get this handled easily;
  /// when testing, pass a mock here
  public ListViewModel( ...., ICustomerEditorService editorService )
  {
    ....
  }

  private void OnEditButtonClicked()
  {
    var editedCustomer = editorService.EditCustomer( GetSelectedCustomer() );
    //do stuff with editedCustomer
  }
}

/// A real implementation
class CustomerEditorService
{
  public Customer EditCustomer( Customer toEdit )
  {
    var vm = new CustomerEditorViewModel( toEdit );
    var view = new CustomerEditorView( vm );
    if( myWindowManager.ShowDialog( view ) == Cancel )
      return null;
    return vm.Customer;
  } 
}

Upvotes: 3

Related Questions