Skip to content
This repository was archived by the owner on Aug 27, 2020. It is now read-only.

Assigning View Models and passing parameters

Mark Smith edited this page Jun 4, 2018 · 2 revisions

Assigning View Models and passing parameters

There are two approaches you can use when assigning view models.

Note: These implementation details are specific to the FormsNavigationService implementation. If you are using your own navigation service, these instructions might not apply.

Assigning the view model as part of the navigation.

The first is where you pass the view model as the state parameter to one of the navigation APIs. In this case, the Page should not assign it's own BindingContext.

// Called with VM as "state" parameter. In this case, the 
// passed stateParameter will be null in InitializeAsync.
var navService = ...;
await navService.NavigateAsync(SomePageKey, new MyViewModel());

In this case, the navigation service will note that the BindingContext is null on the identified page, and it will use the passed state object. If the object implements IViewModelNavigationInit, it will be called prior to navigation.

This approach lets you setup the view model object however you need to - passing parameters by setting properties or even as constructor parameters. For example:

var childViewModel = new ChildViewModel { 
   Item = this.SelectedItem, 
   User = this.LoggedOnUser, 
   ... 
};
await navService.NavigateAsync(SomePageKey, childViewModel);

However, it also tends to require that the caller (typically another view model) has knowledge of the child view model which can create undesirable dependencies.

Creating the view model in the view

The second approach is to assign the view model as part of the Page construction. This can be done in the constructor directly (assign the BindingContext), or through IoC using the DependencyService. As an example, we can assign it in XAML using the DependencyServiceExtension:

<Page xmlns:inf="clr-namespace:XamarinUniversity.Infrastructure;assembly=XamU.Infrastructure" ...
     BindingContext="{inf:DependencyService {x:Type vm:ChildViewModel}}">

With this approach, the Page will have a BindingContext assigned already and the FormsNavigationService implementation will detect this and not assign it from the passed state parameter. Instead, the state will be forwarded to the IViewModelNavigationInit.InitializeAsync method (if present). This allows parameters to be passed to the view model:

// could be dynamic, Tuple, simple or complex value..
MyParameters someParameters = ...; 
// Passed as "object" value.
await navService.NavigateAsync(SomePageKey, someParameters);

Then we can get the passed parameters as part of the InitializeAsync implementation. Here we implement the interface directly, but you can also rely on the SimpleViewModel override as well if you are using it as a base class for your view models.

public class ChildViewModel : IViewModelNavigationInit
{
   ...
   public Task InitializeAsync(object stateParameter)
   {
      MyParameters someParameters = (MyParameters) stateParameter;
      ...
      return Task.CompletedTask; // or await something..
   }
}