Share via

register pages in shell

Eduardo Gomez 4,316 Reputation points
2024-03-18T00:37:36.75+00:00

everything is working fine and dandy, but there is one thing tha is bugging me

if I am declaring everything dynamically

why I still need to declare

   <ShellContent
        ContentTemplate="{DataTemplate pages:StartupPage}"
        Route="StartupPage"
        Shell.FlyoutBehavior="Disabled"
        Shell.FlyoutItemIsVisible="False" />
    <ShellContent
        ContentTemplate="{DataTemplate pages:LoginPage}"
        Route="LoginPage"
        Shell.FlyoutBehavior="Disabled"
        Shell.FlyoutItemIsVisible="False" />
    <ShellContent
        ContentTemplate="{DataTemplate pages:NoInternetPage}"
        Route="NoInternetPage"
        Shell.FlyoutBehavior="Disabled"
        Shell.FlyoutItemIsVisible="False" />
    <ShellContent
        ContentTemplate="{DataTemplate pages:RoleSelectionPage}"
        Route="RoleSelectionPage"
        Shell.FlyoutBehavior="Disabled"
        Shell.FlyoutItemIsVisible="False" />


becouse in my flyouthelper, I have a method to handle this

    public static void GeetDefaultMenuItems() {
        var defaultItems = new List<ShellContent> {
             new() { ContentTemplate = new DataTemplate(typeof(StartupPage)),
                Route = nameof(StartupPage), FlyoutItemIsVisible = false },
            new() { ContentTemplate = new DataTemplate(typeof(LoginPage)),
                Route = nameof(LoginPage), FlyoutItemIsVisible = false },
            new() { ContentTemplate = new DataTemplate(typeof(NoInternetPage)),
                Route = nameof(NoInternetPage), FlyoutItemIsVisible = false },
            new() { ContentTemplate = new DataTemplate(typeof(RoleSelectionPage)),
                Route = nameof(RoleSelectionPage), FlyoutItemIsVisible = false }
        };
        Shell.Current.Items.Clear();
        foreach(var item in defaultItems) {
            Shell.Current.Items.Add(item);
        }
    }
}


So, what I want to do, is to use this instead

I already try to use it in the app.cs

And startup page

public class StartupPageViewModel : BaseViewModel {
    private readonly IAppService _appService;
    public StartupPageViewModel(IAppService appService) {
        _appService = appService;
        CheckAuth();
    }
    private async void CheckAuth() {
        var currentUserAsJson = await SecureStorage.GetAsync(Constants.LOGGED_USER);
        if(string.IsNullOrEmpty(currentUserAsJson)) {
            if(DeviceInfo.Platform == DevicePlatform.WinUI) {
                Shell.Current.Dispatcher.Dispatch(async () => {
                    await Shell.Current.GoToAsync($"//{nameof(LoginPage)}", true);
                });
            } else {
                await Shell.Current.GoToAsync($"//{nameof(LoginPage)}", true);
            }
        } else {
            var loggedUser = await StorageHelper<DemyUser>.GetObjFromStorageAsync();
            FlyoutHelper.CreateFlyoutHeader(loggedUser);
            FlyoutHelper.CreateFlyoutMenu(loggedUser?.CurrentRole!);
            await NvigationHelper.NavigatoToDashboardRoleAsync(loggedUser?.CurrentRole!);
        }
    }
}
Developer technologies | .NET | .NET Multi-platform App UI
0 comments No comments

Answer accepted by question author

Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 50,166 Reputation points Microsoft External Staff
2024-03-18T05:32:34.9266667+00:00

Hello,

After testing, you can create and register a ShellItem only from the cs code with the following steps.

Step 1. Create AppShell without item in xaml.

<Shell
    x:Class="MauiApp9.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiApp9"
    Shell.FlyoutBehavior="Flyout"
    Title="MauiApp9">


</Shell>

Step 2. Create a ShellItem via a static method.

public static class FlyoutHelper
{
    public static void GeetDefaultMenuItems()
    {
        var defaultItems = new List<ShellContent> {
            new() { Title="MainPage", ContentTemplate = new DataTemplate(typeof(MainPage)),
                Route = nameof(MainPage), FlyoutItemIsVisible = true },
            new() { Title="Page1", ContentTemplate = new DataTemplate(typeof(NewPage1)),
                Route = nameof(NewPage1), FlyoutItemIsVisible = true },
            new() { Title="Page2", ContentTemplate = new DataTemplate(typeof(NewPage2)),
                Route = nameof(NewPage2), FlyoutItemIsVisible = true },
        };
        if(Shell.Current != null )
        {
            Shell.Current.Items.Clear();
            foreach (var item in defaultItems)
            {
                Shell.Current.Items.Add(item);
            }
        }


   }
}

Step 3. Call the method implemented in the second step in the shell's OnAppearing method.

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        
    }
    protected override void OnAppearing()
    {
        base.OnAppearing();
        FlyoutHelper.GeetDefaultMenuItems();
    }
}

In addition, if you want to call the OnAppearing method from a ViewModel, you need to use the EventToCommand feature provided by the CommunityToolkit.

Best Regards,

Alec Liu.


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Was this answer helpful?

0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.