Passing data to view models in Xamarin.Forms

June 25th 2021 Xamarin

Navigation in Xamarin.Forms Shell is based on URIs. Parameters are passed between pages in the query string. I just recently learned that as an alternative to using the QueryProperty attribute, you can also implement the IQueryAttributable interface. I also didn't realize that you don't necessarily need to implement either of them in your page class. They work just as well in the class assigned to the page's BindingContext, which is typically your view model.

These two realizations have drastically changed my approach to parameter processing. Being able to do this directly in the view model class meant that I no longer had to manually pass the values from the page to the view model.

The ability to process all query parameters in a single method had an even bigger impact. Having the values assigned directly to properties is handy when you just need to display them on the target page.

But if you need to trigger an action based on their value (such as loading data), it's much easier to do all the processing in a single method because it's only triggered once:

public void ApplyQueryAttributes(IDictionary<string, string> query)
  if (query.TryGetValue("param1", out var param1))
    this.Param1 = param1;

  if (query.TryGetValue("param2", out var param2))
    this.Param2 = param2;

  // load data or do other processing based on parameter values

If you use the QueryProperty attribute to assign values directly to properties, you could trigger the action in the property setter. But if you pass more than one property value, you don't know when all of them have been set so you could trigger the action only then.

The ApplyQueryAttributes method is also called when the user navigates back to the same page. Any query parameters contained in the URI that triggered the backward navigation can also be processed in this method. This opens up many interesting scenarios:

  • You could simply pass the same set of parameters to change what is displayed on the page.
  • You could pass a flag indicating whether the data should be reloaded because it changed.
  • You could return a value from a modal page corresponding to a user decision.

A sample project in my GitHub repository shows the ApplyQueryAttributes method in action for processing parameters in both forward and backward navigation.

Only being able to pass parameters between pages in the query string is limiting, but having the option to manually process that query string if needed can make at least some use cases easier to implement.

Creative Commons License