How can I pass data to a ShellSection’s ShellContent to reuse the same page for different purposes on a Xamarin.Forms Shell application?

Franco Scarpa 21 Reputation points
2020-12-27T10:43:49.873+00:00

I’m building a Xamarin.Forms Shell application which provides a flyout and no bottom tabs. The UI is like this:

51481-tlfng.png

The first mockup on the left shows the flyout opened and its items. As you can see, Item1 has its personal page. At the same time, Item2, Item3, and Item4 are grouped both as top tabs and flyout items (I got this result using the FlyoutDisplayOptions.AsMultipleItems value on the ShellSection element). I want to make the pages with the Ipsum, Dolor, and Sit titles to share the same page, kind of a “singleton” updated depending on the selected top tab (or selected flyout item). This lets me use a single page instead of creating different ones to host the various contents. On a Xamarin.Forms Shell application, we can pass data while navigating to pages, using appropriate properties on the view model of the target page. However, I don’t figure out how to use this with a ShellSection element. In my mind, I plan to clear the content of the shared page when navigating to a different tab. To give you an example, let‘s suppose I’m in the Item2 tab, and I click on the Item3 tab (on in the relative flyout item). I plan to:

  1. Clear the content of the shared page.
  2. Navigate to the new top tab (even if I clicked on the flyout item).
  3. Update the shared page with the new content.

I tried using routes to pass data to the shared page; however, doing so overrides the default behavior of the application (it navigates to a fullscreen page instead of the tabbed one), so I lose the ability to go to the specific tab. Maybe routes are the way to go, but I don’t know how to manipulate them to navigate the shared page passing data. So far, I wrote this in the AppShell.xaml.cs file:

var fi = new FlyoutItem    { FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems };  
var ss = new ShellSection  { FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems };  

foreach (var kind in kinds) {   // "kinds" is obtained from an external service  
   var sc = new ShellContent { Title = kind.Name, ContentTemplate = new KindPage(kind.Id) };      
   ss.Items.Add(sc);  
}  

fi.Items.Add(ss);  
ShellItems.Items.Add(fi);  

Online, I read that I could pass a parameter to the constructor of KindPage. However, this approach is not well suited for this situation since I need something (that is, cleaning the page to prepare it to host the new tab’s content) when the page appears, not when it’s constructed. Moreover, this would cause the creation of different KindPage objects, one for each tab. Instead, I think a single page would be more well suited. In a nutshell, I would need to specify the Route property of the different ShellContent elements like this: standard route defined by the inner behavior of Xamarin.Forms Shell plus a parameter to let me differentiate the content to be displayed.

So far, overriding the Route property with something like:

Route = "//KindPage?kind=1";  

causes the navigation system to obviously bypass the page with the top tabs. Instead, it creates a fullscreen page. I want the top tabs to be maintained. To summarize, I need to define a parameter when navigating to a top tab page (which is kind of a “singleton” page, whose content is reset to host the new content relative to the selected tab). Do you know a way to do this?

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,294 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,245 questions
{count} votes