Imagine I have a View that shows a generic list of customers. In this case I would implement a CustomersViewModel
with a RelayCommand
bound to a XAML Button, to download it and to populate an ObservableCollection
of Customer
, bound to a ListView
.
If I want to define a CustomerDetailView
, a view to show some other information about a Customer, I would create a CustomerDetailViewModel
, a CustomerView
, and repeat the same logic. But the difference is that the ViewModel has to take the selected Customer as a parameter, while the CustomersViewModel
could be shown every time without external parameters.
In a WinForm solution I would put a parameter to construct the form the object I need.
My question is: what's the correct way to implement such navigation in order to respect MVVM pattern?
My navigation logic:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var nav = new NavigationService();
nav.Configure("CustomersView", typeof(CustomersView));
nav.Configure("CustomerDetailView", typeof(CustomerDetailView));
SimpleIoc.Default.Register<INavigationService>(() => nav);
SimpleIoc.Default.Register<CustomersViewModel>();
SimpleIoc.Default.Register<CustomerDetailViewModel>();
}
private RelayCommand _navigateToCustomerDetailCommand;
public RelayCommand NavigateToCustomerDetailCommand
{
get
{
return _navigateToCustomerDetailCommand
?? (_navigateToCustomerDetailCommand = new RelayCommand(
() =>
{
_navigationService.NavigateTo("CustomerDetail");
}
{
}
The options I thought:
Pass a parameter in some way to "NavigateTo" function, and define the relative ViewModel with such parameter in the constructor. I didn't find a way to do this, although it seems reasonable to me.
Navigate as above, then send a Message to the ViewModel. This idea is working, but I'm not convinced about it. In my opinion it seems a way to over complicate a simple thing.
return _navigateToCustomerDetailCommand ?? (_navigateToCustomerDetailCommand = new RelayCommand( () => { _navigationService.NavigateTo("CustomerDetail"); Messenger.Default.Send(new CustomMessageCustomerSelected(SelectedCustomer)); }
And in the ViewModel listen for that message:
public CustomerDetailViewModel(NavigationService _navigationService) { // ... Messenger.Default.Register<CustomMessageCustomerSelected> ( this, (action) => { SelectedCustomer = action.Value; } ); // ... }