What would be MVVM way of passing a parameter to the initial View's ViewModel, which is loaded into the detail area when navigating to the TabbedPage?
An example use case could be that I'm located in orders view, and click on one of the orders, it navigates me to the tabbed page that has order details view as the first tab. How do I pass the order details to the OrderDetailsViewModel? When using TabbedPage I have an additional layer in between. In my mind, the order details would have to be passed in a similar flow to this: OrdersViewModel ->TabbedPageViewModel -> OrderDetailsViewModel.
Is something like MessagingCenter viable solution for this type of communication?
I don't use MVVM Framework, but I wonder how would a frameworks like MvvmCross, Prism, MVVM Light would handle this scenario?
The OrderDetailsViewModel
should be included in the TabbedPageViewModel
as a property, then when you pass parameters to TabbedPageViewModel
, OrderDetailsViewModel
could also notify the value.
The custom TabbedPage's Xaml:
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Demo.MyTabbedPage" xmlns:local="clr-namespace:Demo"> <!--Pages can be added as references or inline--> <local:OrderDetailsView Title="Tab 1" BindingContext="{Binding OrderDetailsViewTab}"/> <local:SecPage Title="Tab 2" BindingContext="{Binding SecViewTab}"/> <local:ThirdPage Title="Tab 3" BindingContext="{Binding ThirdViewTab}"/> </TabbedPage>
code behind for TabbedPageViewModel
:
public class MyTabbedPageViewModel { public OrderDetailsViewModel OrderDetailsViewTab { set; get; } public SecViewModel SecViewTab { set; get; } public ThirdViewModel ThirdViewTab { set; get; } public MyTabbedPageViewModel(string orderID) { OrderDetailsViewTab = new OrderDetailsViewModel { ... }; //... } }
When you want to navigate to this tabbed page, you could pass parameters like:
var tabbedPage = new MyTabbedPage(); tabbedPage.BindingContext = new MyTabbedPageViewModel(...); Navigation.PushAsync(tabbedPage);
Answers
The
OrderDetailsViewModel
should be included in theTabbedPageViewModel
as a property, then when you pass parameters toTabbedPageViewModel
,OrderDetailsViewModel
could also notify the value.The custom TabbedPage's Xaml:
code behind for
TabbedPageViewModel
:When you want to navigate to this tabbed page, you could pass parameters like:
Thanks for the answer
But what if my OrderDetailsViewModel has some services, that needs to be injected?
Should I resolve the dependencies in MyTabbedPageViewModel?
Or when I'm navigating to MyTabbedPageViewModel from OrdersViewModel, the OrdersViewModel should get the services through constructor injection and pass it down to MyTabbedPageViewModel constructor, which it will again forward to OrderDetailsViewModel constructor?
It would be perfect if I could use InitializeAsync method that comes from ViewModelBase to pass the orderID instead of using the constructor. I use this book as a reference for my architecture:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/
https://github.com/dotnet-architecture/eShopOnContainers/tree/1b7200791931f33c94206822a69644ca820bb0dc/src/Mobile/eShopOnContainers/eShopOnContainers.Core
You can expand my sample constructor to inject other services you want to use:
You can also record this ID via a private proerty of MyTabbedPageViewModel, then you can pass this id to OrderDetailsViewModel when you want to do that instead of setting it to
OrderDetailsViewTab
directly.