-
Notifications
You must be signed in to change notification settings - Fork 37
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.
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.
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..
}
}