DEV Community

David Ortinau for .NET

Posted on

1

Hack: Hijack Tabs for Custom Actions in Xamarin.Forms

I was asked yesterday how to customize tabs to execute actions rather than routing to a page. This is not something we can do by design, but since when has that ever stopped us before! Challenge accepted.

So I took a few minutes to whip of this variation of an existing sample that shows how you can have your first page be a login screen without tabs, and then a main screen with tabs.

Kick things off by creating a tab without any real content.

<Tab Title="Back" Route="back" Icon="{StaticResource IconBack}">
<ShellContent
ContentTemplate="{DataTemplate local:EmptyRoutePage}" />
</Tab>
view raw HackTabs.xaml hosted with ❤ by GitHub

Noticed the content there is aptly named because the page is blank.

Now we need to register to handle the Navigating event on the AppShell.xaml.

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ShellLoginSample.AppShell"
Navigating="Shell_Navigating"
>
view raw Navigating.xaml hosted with ❤ by GitHub

And now we are ready for the interception! Making sure that we aren't handling the boot route when e.Current is null, we first grab the deferral token so Shell knows to not immediately complete the routing request.

Next, we use the Route to identify which tab was tapped, and then we can execute our custom intentions. In this case we are going to trigger a "back" action which will work if there is actually a page to be popped off the stack. As you can see we have another tab here that will log out of the app.

Finally, we need to complete the deferred navigation request so Shell knows we are finished.

private void Shell_Navigating(object sender, ShellNavigatingEventArgs e)
{
if(e.Current != null) {
var deferral = e.GetDeferral(); // hey shell, wait a moment
// intercept navigation here and do your custom logic.
// continue on to the destination route, cancel it, or reroute as needed
// e.Cancel(); to stop routing
// deferral.Complete(); to resume
if(e.Target.Location.OriginalString.Contains("back"))
{
e.Cancel();//don't actually go to a route called back
Shell.Current.GoToAsync(".."); // this is the universal "back" in Shell
}
else if (e.Target.Location.OriginalString.Contains("logout"))
{
e.Cancel();
Shell.Current.GoToAsync("//login");
}
deferral.Complete();
}
}

That's it! Check out the video from Twitter, and the complete code is on GitHub.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay