Getting the flyout menu to work in Xamarin Forms the way I want it to has been a major pain. I'm trying to get a certain menu item (My Stats) to go to a certain page if the user is logged in, or to a different page if the user is not (The login page). I have attempted two different approaches with no success.
Approach 1
First I tried setting the flyout Item in XAML with specified route in Shell Content like so:
<FlyoutItem Title="My Stats" Icon="icon_feed.png">
<ShellContent x:Name="shellContent_myStats" Route="MyStatsPage" ContentTemplate="{DataTemplate local:MyStatsPage}" />
</FlyoutItem>
Then I would modify the route programmtically when the user logs in/out:
//Logging Out
shellContent_myStats.ContentTemplate = new DataTemplate(typeof(LoginPage));
Routing.SetRoute(shellContent_myStats, "LoginPage");
...
//Logging In
shellContent_myStats.ContentTemplate = new DataTemplate(typeof(MyStatsPage));
Routing.SetRoute(shellContent_myStats, "MyStatsPage");
I could not get this to work. For whatever reason, only the first piece to get executed would take effect. For example, if I started the app while logged out, it would direct to the login page as expected but would not switch over once I log out. The reverse is true as well if I start the app while logged in, it navigates to the "My Stats" page as expected, but will continue to do so even after I log out.
I have tried a few different variations of the above code to no avail.
Approach 2
The second approach I tried, was instead specifying a menu item in XAML with an OnClick event handler like so:
<MenuItem Text="My Journey" StyleClass="MenuItemLayoutStyle" Clicked="OnMyStatsClicked"/>
Code behind:
public AppShell()
{
//Route now needs to be registered in page constructor
Routing.RegisterRoute(nameof(MyStatsPage), typeof(MyStatsPage));
...
public async void OnMyStatsClicked(object sender, EventArgs e)
{
Shell.Current.FlyoutIsPresented = false;
if (LoggedIn)
{
// Prefixing with `//` switches to a different navigation stack instead of pushing to the active one
await Shell.Current.GoToAsync($"//{nameof(MyStatsPage)}");
}
else
{
await Shell.Current.GoToAsync($"//{nameof(LoginPage)}");
}
}
...
Now when I select the menu item with this setup (while logged in), it throws the following error:
System.Exception: 'Global routes currently cannot be the only page on the stack, so absolute routing to global routes is not supported. For now, just navigate to: MyStatsPage'
If I follow the suggestion given by removing the two slashes in the route ("//"), the navigation works, but then the flyout menu is not available in the top left and is replaced with a back button. This is not desired, I want the menu to still be available. Why can't I use absolute routing on a route defined in the code behind..?
I appreciate any suggestions on either of the two methods mentioned to get this to work. Been at it for days trying to do something seemingly so simple.. Thanks