2

I want to add this StackLayout in the menu item and change the visibility at runtime.

<StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label Text="Shop Autographs" FontSize="14" TextColor="Black" HorizontalOptions="CenterAndExpand" Margin="0,0,20,0"/>

                    <ImageButton Source="{Binding ShopAutographsMenuIconSource}" Command="{Binding ShopAutographsMenuCommand}" HeightRequest="15" BackgroundColor="Transparent" Margin="0,0,10,0"/>
                </StackLayout>

                <StackLayout x:Name="shopAutographMenu" IsVisible="{Binding IsShopAutographMenuVisible}">
                    <Label Text="Most Popular" HorizontalOptions="StartAndExpand"/>
                    <Label Text="Shop By Category" HorizontalOptions="StartAndExpand"/>
                </StackLayout>
            </StackLayout>

This is what I want to achieve

1 Answers1

3

According to your description, you want to add sub menu item in Shell one menu item.

Firstly, I create DataTemplateSelector, to detect menu item title is Header or other, if it is Header, choose NavigationHeaderTemplate, then choosing NavigationItemTemplate.

public class FlyoutItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate NavigationHeaderTemplate { get; set; }
    public DataTemplate NavigationItemTemplate { get; set; }
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        if (item is ShellGroupItem && ((ShellGroupItem)item).Title == "Header")
        {
            // Make sure a header item is not clickable.
            ((ShellGroupItem)item).IsEnabled = false;
            return NavigationHeaderTemplate;
        }
        else
            return NavigationItemTemplate;
    }
}

Then adding the regular ItemTemplate, the new Header template and the FlyoutItemTemplateSelector control to the Shell.Resources tag in AppShell.xaml:

 <DataTemplate x:Key="FlyoutItemTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.25*" />
                    <ColumnDefinition Width="0.75*" />
                </Grid.ColumnDefinitions>
                <Label
                    Margin="20,0,0,0"
                    FontSize="30"
                    HeightRequest="45"
                    Text="{Binding Icon}"
                    TextColor="Black"
                    VerticalTextAlignment="Center" />
                <Label
                    Grid.Column="1"
                    Text="{Binding Title}"
                    TextColor="Black"
                    VerticalTextAlignment="Center" />
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="FlyoutHeaderTemplate">
            <StackLayout Orientation="Vertical">
                <Label
                    Margin="20,0,0,0"
                    HeightRequest="35"
                    Text="{Binding Title}"
                    TextColor="Black"
                    VerticalTextAlignment="Center">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
                    </Label.GestureRecognizers>


                </Label>
            </StackLayout>
        </DataTemplate>
        <controls:FlyoutItemTemplateSelector
            x:Key="FlyoutTemplateSelector"
            NavigationHeaderTemplate="{StaticResource FlyoutHeaderTemplate}"
            NavigationItemTemplate="{StaticResource FlyoutItemTemplate}" />

Add the Shell.ItemTemplate to the main Shell tag.

<Shell
x:Class="shellsample.AppShell"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:shellsample"
xmlns:local="clr-namespace:shellsample.Views"
Title="shellsample"
Shell.ItemTemplate="{StaticResource FlyoutTemplateSelector}">

Finally, using FlyoutItem.

<FlyoutItem
    Title="About"
    FlyoutDisplayOptions="AsMultipleItems"
    Shell.TabBarIsVisible="False">
    <ShellContent Title="Header" ContentTemplate="{DataTemplate local:AboutPage}" />
    <ShellContent
        Title="sub1"
        ContentTemplate="{DataTemplate local:AboutPage}"
        IsVisible="{Binding isvisible}" />
    <ShellContent
        Title="sub2"
        ContentTemplate="{DataTemplate local:AboutPage}"
        IsVisible="{Binding isvisible}" />
    <ShellContent
        Title="sub3"
        ContentTemplate="{DataTemplate local:AboutPage}"
        IsVisible="{Binding isvisible}" />

</FlyoutItem>
<FlyoutItem Title="Browse" Icon="icon_feed.png">
    <ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" />
</FlyoutItem>

public partial class AppShell : Xamarin.Forms.Shell, INotifyPropertyChanged
{    
    private bool _isvisible;
    public bool isvisible
    {
        get { return _isvisible; }
        set
        {
            _isvisible = value;
            OnPropertyChanged("isvisible");
        }
    }
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
        Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
      
        this.BindingContext = this;
    }

    private async void OnMenuItemClicked(object sender, EventArgs e)
    {
        await Shell.Current.GoToAsync("//LoginPage");
     
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    protected override void OnNavigating(ShellNavigatingEventArgs args)
    {
        base.OnNavigating(args);
    }

    private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {
        isvisible = !isvisible;
    }
}

Please note: using Xamarin.forms version 4.8.0.1821

The screenshot:

enter image description here

enter image description here

Cherry Bu - MSFT
  • 10,160
  • 1
  • 10
  • 16