We're trying to follow an MVVM pattern as supported by Xamarin.Forms, but have had some trouble figuring out the best way to respect MVVM conventions while navigating from a master page to a detail page.
Using this as an example:
https://developer.xamarin.com/guides/cross-platform/xamarin-forms/user-interface/xaml-basics/data_bindings_to_mvvm/
Forms supports assigning a view the type of its viewmodel, so the viewmodel is created automatically:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="WidgetProjectNamespace"
x:Class="WidgetProjectNamespace.MasterPage"
Title="Master Page">
<ContentPage.BindingContext>
<local:MasterViewModel />
</ContentPage.BindingContext>
<StackLayout>
<!-- A list of widgets goes here -->
</StackLayout>
</ContentPage>
Let's say I have a master page with a simple list of items. The MasterViewModel will know how to retrieve the list of items and display them:
public class MasterViewModel
{
...
public void Load()
{
var widgets= widgetRepository.Fetch();
WidgetListItemSource = widgets;
}
}
Tapping on an item will navigate to a detail page for that item. When I handle the click event, I need to navigate to a detail page by pushing it onto the stack:
Item.OnTapped += (s, e) => Navigation.PushAsync(new DetailPage());
That detail page can also have its viewmodel created automatically:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="WidgetProjectNamespace"
x:Class="WidgetProjectNamespace.DetailPage"
Title="Detail Page">
<ContentPage.BindingContext>
<local:DetailViewModel />
</ContentPage.BindingContext>
<!-- Some content describing the widget's details goes here -->
</ContentPage>
But how will the DetailViewModel know what model it needs to display?
The only way to do this seems to be to tell the page directly:
Item.OnTapped += (s, e) => Navigation.PushAsync(new DetailPage(itemModel));
But this seems backwards. The viewmodel should tell the page what to display, not the other way around.
Am I missing something? Is there a way in vanilla Xamarin.Forms to navigate to a detail page and respect MVVM principles?