Frank Mehlhop
Frank Mehlhop

Reputation: 2222

Maui How to add a button at the Shell to navigate to a page?

I have a Maui application with flyout menu. Additional I like to have a button on the Shell at the right end "profile". From there the ProfilePage should be opened. (instead using the flyout menu).

How should I implement the button at the shell?

How should I handle the click event (or ICommand) to open the ProfilePage?

I tried using the TitleView (also ItemTemplate and ToolbarItems), but the page title gets lost (I like to keep the standard), the button is not on the right end and I can't find out how to navigate to ProfilePage by clicking the button:

<Shell
x:Class="Mandatos.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MyProject.Views"
FlyoutBehavior="Flyout" >

<Shell.TitleView >
    <HorizontalStackLayout>
        <Label FontSize="30" Margin="30" Text="{Binding Title}" />
        <Button Text="Profile" WidthRequest="100" HorizontalOptions="End"
                Clicked="Button_OnClicked" BackgroundColor="red"/>
    </HorizontalStackLayout>
</Shell.TitleView>

<FlyoutItem Title="First" >
    <ShellContent ContentTemplate="{DataTemplate views:FirstPage}" />
</FlyoutItem>

<FlyoutItem Title="Second">
    <ShellContent ContentTemplate="{DataTemplate views:SecondPage}" />
</FlyoutItem>

<!-- more pages.. -->

It should look like that: enter image description here

Upvotes: 0

Views: 4277

Answers (2)

Liyun Zhang - MSFT
Liyun Zhang - MSFT

Reputation: 14269

I created a new project to test your code and found that the <HorizontalStackLayout> will not work perfectly in the Shell.TitleView. So I used the grid instead of stacklayout.

In addition, you said

the page title gets lost (I like to keep the standard)

This should be the Text="{Binding Title}" doesn't work. You can refer to my sample which get the effect you want.

In the AppShell.xaml:

 <Shell.TitleView>
        <Grid ColumnDefinitions="9*,1*">
            <Label x:Name="title" HorizontalOptions="Start" Grid.Column="0" VerticalTextAlignment="Center"/>
            <Button Text="test" Grid.Column="1" Clicked="Button_Clicked" BackgroundColor="Red" HorizontalOptions="Start"/>
        </Grid>
    </Shell.TitleView>
    <ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />
    <ShellContent
        Title="NewPage"
        ContentTemplate="{DataTemplate local:NewPage1}"
        Route="NewPage" />

And in the code behind:

public partial class AppShell : Shell
{
      
      public AppShell()
      {
            InitializeComponent();
      }

    private void Button_Clicked(object sender, EventArgs e)
    {
        // do the navigation you want
    }
    protected override void OnNavigated(ShellNavigatedEventArgs args)
    {
        base.OnNavigated(args);
        title.Text = Shell.Current.CurrentItem.Title;
        // make the title always show correctly
    }
}

And the result image:

enter image description here

Upvotes: 2

H.A.H.
H.A.H.

Reputation: 3897

The following is just my point of view, feel free to completely ignore it:

I understand and use the Shell, exactly as a shell. It is the external shape of my application, nothing more. And as such, it must remain empty.

I do not say it should not contain any logic. In fact, some of the events there are the only way to solve very specific navigation problems. But I advise you to keep it as clean as possible.

I would add everything else to the Content Pages instead of the Shell. What method I would use - I do not know. Maybe toolbar. Maybe title view. Maybe I will separate it as tab or flyout item. Really depends on the situation.

But this is in the ContentPage, not the Shell. (And handled after that by their ViewModels)

Upvotes: 0

Related Questions