Tuesday, 9 March 2021

Process navigation data using IQueryAttributable in Xamarin.Forms Shell apps

I recently discovered, courtesy of @PureWeen, another mechanism for receiving navigation data in Xamarin.Forms Shell apps.

If you write Shell apps, you’ll know that the mechanism for passing data between pages is to pass it as query parameters using URI-based navigation. Then, in your receiving class (be it a page, or a view model), you decorate the class with a QueryPropertyAttribute for each query parameter. This works quite well, but it can be a pain having to add a QueryPropertyAttribute for each item of data that gets passed. In addition, because each QueryPropertyAttribute sets a property, you can end up with multiple pieces of plumbing code just to receive data.

So what’s the solution? Enter the oddly named IQueryAttributable interface.

Process navigation data using a single method

IQueryAttributable is a Xamarin.Forms interface that specifies that an implementing class must implement a method named ApplyQueryAttributes. This method has a query argument, of type IDictionary<string, string>, that contains any data passed during navigation. Each key in the dictionary is a query parameter id, with its value being the query parameter value.

For example, the following code shows a view model class that implements IQueryAttributable:

public class MyViewModel : IQueryAttributable
{
    public void ApplyQueryAttributes(IDictionary query)
    {
        // The query parameter requires URL decoding.
        string name = HttpUtility.UrlDecode(query["name"]);
        ...
    }
    ...
}

In this example, the ApplyQueryAttributes method retrieves the value of the name query parameter from the URI in the GoToAsync method call. Then, whatever custom logic is desired can be executed. Note that query parameter values that are received via the IQueryAttributable interface aren’t automatically URL decoded.

It’s also possible to process multiple items of navigation data:

public class MyViewModel : IQueryAttributable
{
    public void ApplyQueryAttributes(IDictionary query)
    {
        // The query parameters require URL decoding.
        string name = HttpUtility.UrlDecode(query["name"]);
        string location = HttpUtility.UrlDecode(query["location"]);
        ...
    }
    ...
}

In this example, the ApplyQueryAttributes method retrieves the value of the name and location query parameters from the URI in the GoToAsync method call.

The advantage of using this approach is that navigation data can be processed using a single method, which can be useful when you have multiple items of navigation data that require processing as a whole. Compare that against the QueryPropertyAttribute approach, with multiple properties per item of data, and it’s a no brainer which is more elegant.

Want to know more about Shell navigation? Then see Xamarin.Forms Shell navigation.

No comments:

Post a comment