Reputation: 1024
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
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