I'm working on a .Net MAUI shell application project where I have a shell with multiple tabs in the logbook flyout. The requirement is for each tab to display a different set of log entries, for example, 'all' log entries or only those log entries created in the past 24 hours.
I have been trying to execute a RelayCommand in my MainPageViewModel whenever a tab is selected. The functionality of the RelayCommand is to update the log entries based on the selected route. However, I'm facing an issue where the BindingContext is always null when the OnShellNavigating event is fired, causing the TabSelectedCommand to never be executed. Here's my code:
AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
xmlns:views="clr-namespace:Logbook.Views"
xmlns:viewModel="clr-namespace:Logbook.ViewModels"
xmlns:behaviors="clr-namespace:Logbook.Behaviours"
x:Class="Logbook.AppShell"
x:Name="shell">
<FlyoutItem Title="Logbook" >
<FlyoutItem.Icon>
<FontImageSource FontFamily="FASolid"
Color="{AppThemeBinding
Dark ={StaticResource White},
Light={StaticResource Gray500}}"
Glyph="{StaticResource fa_Book}"/>
</FlyoutItem.Icon>
<Tab Title="Past 24 Hours">
<Tab.Icon>
<FontImageSource FontFamily="FASolid"
Color="{AppThemeBinding
Dark ={StaticResource White},
Light={StaticResource Gray100}}"
Glyph="{StaticResource fa_Clock}"/>
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate views:MainPage}"
Route="MainPage\Past24Hours">
</ShellContent>
</Tab>
<Tab Title="All Entries">
<Tab.Icon>
<FontImageSource FontFamily="FASolid"
Color="{AppThemeBinding
Dark ={StaticResource White},
Light={StaticResource Gray100}}"
Glyph="{StaticResource fa_BookOpen}"/>
</Tab.Icon>
<ShellContent ContentTemplate="{DataTemplate views:MainPage}"
Route="MainPage">
</ShellContent>
</Tab>
</FlyoutItem>
MainPageViewModel.cs
public partial class MainPageViewModel : BaseViewModel
{
// ...
[RelayCommand]
async Task TabSelectedAsync(string route)
{
// Filter the log entries by the selected route
// ...
}
// ...
}
When I select a tab, the OnShellNavigating event handler in my TabSelectedBehavior is triggered, but the BindingContext in the MainPageViewModel is always null. As a result, the TabSelectedCommand is never executed.
namespace Logbook.Behaviours;
public class TabSelectedBehavior : Behavior<Shell>
{
protected override void OnAttachedTo(Shell shell)
{
base.OnAttachedTo(shell);
shell.Navigating += OnShellNavigating;
}
protected override void OnDetachingFrom(Shell shell)
{
shell.Navigating -= OnShellNavigating;
base.OnDetachingFrom(shell);
}
private void OnShellNavigating(object sender, ShellNavigatingEventArgs e)
{
if (e.Target?.Location.OriginalString != null)
{
// Get the route from the navigation event
var route = e.Target.Location.OriginalString;
// Invoke the command in the view model passing the route as a command parameter
if (BindingContext is MainPageViewModel viewModel && viewModel.TabSelectedCommand.CanExecute(route))
{
viewModel.TabSelectedCommand.Execute(route);
}
}
}
}
I've tried different approaches, but the issue persists.
Can anyone suggest how can I ensure that the BindingContext is set correctly and not null when the TabSelectedCommand is executed?
Any help or guidance would be greatly appreciated. Thank you!