question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Shell should support setting queryparameters in a ShellContent instance (in XAML)

See original GitHub issue

Description

I would love to be able to set queryparameters in the route for a ShellContent instance so that I can re-use existing pages by passing different data to them.

This is already supported by using something like Shell.Current.GoToAsync(...); but this is only useful when the user is actually navigating. Take a look at this example:

Our goal is that the ReminderPage would show you reminders from a specific day. in this case, the first tab shows reminders from yesterday, the 2nd tab from today and the third one for tomorrow.

<Shell>
    <TabBar>
        <Tab Title="Foo">
            <ShellContent Title="Yesterday" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
            <ShellContent Title="Today" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
            <ShellContent Title="Tomorrow" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
        </Tab>
         <!-- Just some other tab, not relevant -->
        <Tab Title="Bar">
            <ShellContent ContentTemplate="{DataTemplate pages:BarPage}"/>
        </Tab>
    </TabBar>
</Shell>

Currently we are just rendering the same page 3 times with the same data ,so there is no way for the page to know what date it needs to retrieve reminders from. Unless I am mistaken, there is no good way to make this possible? (More on this in the Intended Use-Case paragraph)

Wouldn’t it be great to be able to do the following:

<Tab Title="Foo">
    <ShellContent Route="reminders?date=2021-12-13" Title="Yesterday" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
    <ShellContent Route="reminders?date=2021-12-14" Title="Today" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
    <ShellContent Route="reminders?date=2021-12-15" Title="Tomorrow" ContentTemplate="{DataTemplate pages:ReminderPage}"/>
        </Tab>

Note: Of course this would need to be bindable so the date can be set dynamically.

Note: In my example I re-use the reminders route 3 times. I think that this is also not supported, but it would be great if it was!

Now the ReminderPage could use the queryparameter attribute or implement that query attribute interface mentioned in the docs to deal with this.


This is currently not possible. And this is a feature that people would really like to have. For example, take a look at this SO post or this one. You can find a lot of other questions like this on other sites as well…

Take a look at the answers given by the community on those SO posts. Such workarounds should not be the given standard for a problem like this. This means that implementing this feature would result in better code with a better Shell experience.

Public API Changes

  • ShellContent.Route should support the queryparameters
  • It should be bindable
  • if we make the re-use of reminders as a route possible (like reminders?date=2021-12-31 and reminders?date=2021-12-30 ) (which I believe is currently not allowed), that would also require under-the-hood changes!

Intended Use-Case

I have already explained this in my description. But I can explain why this feature would be super handy:

The current workarounds for this problem can be summarized in these options:

  • I could make 3 different pages (YesterdayPage, TodayPage and TomorrowPage) and set the date there and try to make a View to re-use as much UI logic as possible, but this is super ugly.
  • Or maybe mess around with some binding contexts and MVVM, but Shell currently doesn’t work well with MVVM so I feel like this is a bad idea?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:14
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
AndreKraemercommented, Nov 28, 2022

I’m using this as a workaround @angelru. Maybe this helps. In our case we have a page called CategoryPage and this is used in multiple ShellContents with the same ViewModel. We have to pass a categoryId to the viewmodel however.

This is similar to the solution from @SailDev. However we’re parsing the parameter in the target page so that we don’t have to listen for navigation events in the shell.

appshell.xaml:

        <ShellContent Title="Ensaladas" 
            ContentTemplate="{DataTemplate menu:CategoryPage}" Route="categories/ensaladas" >
        </ShellContent>
        <ShellContent Title="Sopas" 
            ContentTemplate="{DataTemplate menu:CategoryPage}" Route="categories/sopas">
        </ShellContent>
        <ShellContent Title="Tapas" 
            ContentTemplate="{DataTemplate menu:CategoryPage}" Route="categories/tapas">
        </ShellContent>

CategoryPage.xaml.cs

public partial class CategoryPage : ContentPage
{
    public CategoryPage(CategoryViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = _viewModel = viewModel;
    }

    protected override async void OnNavigatedTo(NavigatedToEventArgs args)
    {
        // Hack: Get the category Id
        _viewModel.CategoryId = GetCategoryIdFromRoute();

        await _viewModel.Initialize();  
        base.OnNavigatedTo(args);
    }


    private int GetCategoryIdFromRoute()
    {
        // Hack: As the shell can't define query parameters
        // in XAML, we have to parse the route. 
        // as a convention the last route section defines the category.
        // ugly but works for now :-(
        var route = Shell.Current.CurrentState.Location
            .OriginalString.Split("/").LastOrDefault();
        return route switch
        {
            "ensaladas" => 1,
            "sopas" => 2,
            "tapas" => 3,
            _ => 0,
        };
    }

2reactions
codemonkey85commented, Sep 2, 2022

I strongly agree that this should be something we can do.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add query parameter to a Xamarin Forms Shell route
I used the Shell OnNavigating method and based on the route, I set a static variable which I then use in my viewmodel...
Read more >
Update an Existing Xamarin.Forms App to use Shell
If you have an existing Xamarin.Forms app that was not built with Xamarin.Forms Shell, this article is here to help highlight the changes...
Read more >
Xamarin.Forms Shell : Navigation | by Ajay Palan | Globant
These routes can be registered in AppShell.xaml.cs file and then be used to navigate to required registered page. One or more query parameters: ......
Read more >
Get Started with Shell Using .NET MAUI Preview 12
This article explains the procedure to use Shell in a .NET MAUI application, which is a part of the recent update to .NET...
Read more >
An Introduction to Xamarin Forms Shell
Forms Shell and how it can help. ... according to our example, should be called AppShell.xaml.cs. ... + QueryParameters = //route/page?
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found