Forum Xamarin.Forms

How do I put the flyout item(Exit) at the bottom of the menu?

HamittirpanHamittirpan Member ✭✭✭✭

Hi everyone !

I want to put shell content at the bottom of my shell menu. How do I do this? I would also like to show popup when the user clicks on logout. But the application fails. Note : local: AcoountExit ==> PopupPage

    <FlyoutItem Title="Anasayfa" FlyoutDisplayOptions="AsMultipleItems" Style="{StaticResource BaseStyle}" Icon="ic_action_home.png">
        <ShellContent Title="Kampanyalar" Icon="ic_action_home.png" ContentTemplate="{DataTemplate local:MainCampaing}" />
        <Tab Title="Harita" Route="Harita" Icon="ic_action_location_on.png">
            <ShellContent Route="Harita" Style="{StaticResource BaseStyle}" Title="Harita" Icon="ic_action_location_on.png" ContentTemplate="{DataTemplate local:MapPage}" />
            <ShellContent Route="Liste" Style="{StaticResource BaseStyle}" Title="Liste" Icon="ic_launcher.png" ContentTemplate="{DataTemplate local:MapListPage}" />
        </Tab>
        <ShellContent Title="Barkod" Icon="ic_action_center_focus_weak.png" ContentTemplate="{DataTemplate local:BarcodePage}" />
        <ShellContent Title="Alışveriş" Icon="ic_action_shopping_cart.png" ContentTemplate="{DataTemplate local:WebSite}" />
        <ShellContent Title="Profil" Icon="ic_action_account_circle.png" ContentTemplate="{DataTemplate local:ProfilePage}" />
    </FlyoutItem>
    <FlyoutItem Title="Hizmetler" Icon="ic_action_center_focus_weak.png" Style="{StaticResource BaseStyle}" FlyoutDisplayOptions="AsMultipleItems">
        <ShellContent Title="Markalarımız" Icon="ic_action_style.png" ContentTemplate="{DataTemplate local:BrandsPage}" />
        <ShellContent Title="Alışveriş" Icon="ic_action_shopping_cart.png" ContentTemplate="{DataTemplate local:WebSite}" />
        <ShellContent Title="Hakkımızda" Icon="ic_action_center_focus_weak.png" ContentTemplate="{DataTemplate local:AboutUs}" />
    </FlyoutItem>
        <ShellContent Title="Çıkış Yap" Icon="ic_action_style.png" ContentTemplate="{DataTemplate local:AccountExit}" />
Tagged:

Best Answer

  • ColeXColeX Member, Xamarin Team Xamurai
    edited September 2019 Accepted Answer

    MenuItem can help you .

    Define MenuItem and MenuItemTemplate in xaml like below

     <Shell.MenuItemTemplate>
            <DataTemplate>
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.2*" />
                        <ColumnDefinition Width="0.8*" />
                    </Grid.ColumnDefinitions>
                    <Image Source="{Binding Icon}"
                           Margin="0,200,0,0"             //move the item down
                           HeightRequest="20" />
                    <Label Grid.Column="1"
                           Margin="0,200,0,0"            //move the item down
                           Text="{Binding Text}"
                           FontAttributes="Italic"
                           VerticalTextAlignment="Center" /> 
                </Grid>
            </DataTemplate>
        </Shell.MenuItemTemplate>
    
     <MenuItem Text="Help"
              Icon="help.png"
              Command="{Binding HelpCommand}"
              />
    

    Show popup code behind with Command

    public ICommand HelpCommand => new Command(() => this.DisplayAlert("Logout",null,"ok"));
    

Answers

  • HamittirpanHamittirpan Member ✭✭✭✭

  • ColeXColeX Member, Xamarin Team Xamurai
    edited September 2019 Accepted Answer

    MenuItem can help you .

    Define MenuItem and MenuItemTemplate in xaml like below

     <Shell.MenuItemTemplate>
            <DataTemplate>
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.2*" />
                        <ColumnDefinition Width="0.8*" />
                    </Grid.ColumnDefinitions>
                    <Image Source="{Binding Icon}"
                           Margin="0,200,0,0"             //move the item down
                           HeightRequest="20" />
                    <Label Grid.Column="1"
                           Margin="0,200,0,0"            //move the item down
                           Text="{Binding Text}"
                           FontAttributes="Italic"
                           VerticalTextAlignment="Center" /> 
                </Grid>
            </DataTemplate>
        </Shell.MenuItemTemplate>
    
     <MenuItem Text="Help"
              Icon="help.png"
              Command="{Binding HelpCommand}"
              />
    

    Show popup code behind with Command

    public ICommand HelpCommand => new Command(() => this.DisplayAlert("Logout",null,"ok"));
    

  • HamittirpanHamittirpan Member ✭✭✭✭
    edited September 2019

    @ColeX Hi Cole. I tried your code on my own project. my screen like this;

    I don't know why my code doesn't work.

  • HamittirpanHamittirpan Member ✭✭✭✭

    @ColeX MainPage.xaml ;

    <?xml version="1.0" encoding="utf-8"?>
    <Shell xmlns="http://xamarin.com/schemas/2014/forms" 
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
           xmlns:d="http://xamarin.com/schemas/2014/forms/design" 
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           xmlns:controls="clr-namespace:GulaylarMenuDesign.Views.Control"
           xmlns:local="clr-namespace:GulaylarMenuDesign.Views" mc:Ignorable="d" 
           x:Class="GulaylarMenuDesign.MainPage"
           FlyoutBackgroundColor="White" ForegroundColor="#050063" TitleColor="#050063"
           DisabledColor="#ED6933" UnselectedColor="White"
           Shell.NavBarIsVisible="True"
           NavigationPage.HasBackButton="False"
           Visual="Material">
    
        <Shell.TitleView>
                <Image Source="DL.png"
                       VerticalOptions="CenterAndExpand"
                       HorizontalOptions="EndAndExpand">
                    <Image.WidthRequest>
                        <OnPlatform x:TypeArguments="x:Double">
                            <On Platform="iOS">80</On>
                            <On Platform="Android">70</On>
                         </OnPlatform>
                    </Image.WidthRequest>
    
                    <Image.HeightRequest>
                        <OnPlatform x:TypeArguments="x:Double">
                            <On Platform="iOS">80</On>
                            <On Platform="Android">70</On>
                         </OnPlatform>
                    </Image.HeightRequest>
                </Image>
        </Shell.TitleView>
    
         <!--<controls:GradientView StartColor="#ED6933" EndColor="White"/>-->
    
        <Shell.Resources>
            <ResourceDictionary>
                <Style x:Key="BaseStyle" TargetType="Element">
                    <!--For the bottom tab-->
                    <Setter Property="Shell.TabBarBackgroundColor" Value="#ED6933" />
                    <Setter Property="Shell.BackgroundColor" Value="#ED6933" />
                </Style>
            </ResourceDictionary>
        </Shell.Resources>
    
        <Shell.FlyoutHeader>
            <ContentView HeightRequest="200">
                <Image Source="Fly1.jpg"
                       Aspect="AspectFill" />
            </ContentView>
        </Shell.FlyoutHeader>
    
        <FlyoutItem Title="Anasayfa" FlyoutDisplayOptions="AsMultipleItems" Style="{StaticResource BaseStyle}" Icon="ic_action_home.png">
            <ShellContent Title="Kampanyalar" Icon="ic_action_home.png" ContentTemplate="{DataTemplate local:MainCampaing}" />
            <Tab Title="Harita" Route="Harita" Icon="ic_action_location_on.png">
                <ShellContent Route="Harita" Style="{StaticResource BaseStyle}" Title="Harita" Icon="ic_action_location_on.png" ContentTemplate="{DataTemplate local:MapPage}" />
                <ShellContent Route="Liste" Style="{StaticResource BaseStyle}" Title="Liste" Icon="ic_launcher.png" ContentTemplate="{DataTemplate local:MapListPage}" />
            </Tab>
            <ShellContent Title="Barkod" Icon="ic_action_center_focus_weak.png" ContentTemplate="{DataTemplate local:BarcodePage}" />
            <ShellContent Title="Alışveriş" Icon="ic_action_shopping_cart.png" ContentTemplate="{DataTemplate local:WebSite}" />
            <ShellContent Title="Profil" Icon="ic_action_account_circle.png" ContentTemplate="{DataTemplate local:ProfilePage}" />
        </FlyoutItem>
        <FlyoutItem Title="Hizmetler" Icon="ic_action_center_focus_weak.png" Style="{StaticResource BaseStyle}" FlyoutDisplayOptions="AsMultipleItems">
            <ShellContent Title="Markalarımız" Icon="ic_action_style.png" ContentTemplate="{DataTemplate local:BrandsPage}" />
            <ShellContent Title="Alışveriş" Icon="ic_action_shopping_cart.png" ContentTemplate="{DataTemplate local:WebSite}" />
            <ShellContent Title="Hakkımızda" Icon="ic_action_center_focus_weak.png" ContentTemplate="{DataTemplate local:AboutUs}" />
        </FlyoutItem>
    
        <Shell.MenuItemTemplate>
            <DataTemplate>
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.2*" />
                        <ColumnDefinition Width="0.8*" />
                    </Grid.ColumnDefinitions>
                    <Image Source="{Binding Icon}"
                           Margin="0,100,0,0"             
                           HeightRequest="20" />
                    <Label Grid.Column="1"
                           Margin="0,100,0,0"           
                           Text="{Binding Text}"
                           FontAttributes="Italic"
                           VerticalTextAlignment="Center" /> 
                </Grid>
            </DataTemplate>
        </Shell.MenuItemTemplate>
    
     <MenuItem Text="Çıkış Yap"
              Icon="ic_action_style.png"
              Command="{Binding HelpCommand}"/>
    
    </Shell>
    
  • ColeXColeX Member, Xamarin Team Xamurai

    Try my project .

  • HamittirpanHamittirpan Member ✭✭✭✭

    @ColeX Thanks to you, my code now works the way I want. I'm just asking you to give me an idea. I've designed cancel and sign out for the warning message.Where and how should I write the actions that will take place if the user clicks the logout button?

  • ColeXColeX Member, Xamarin Team Xamurai

    Where and how should I write the actions that will take place if the user clicks the logout button?

    Inside the command where you defined .. What do you mean by How ? Use DisplayAlert ?

  • HamittirpanHamittirpan Member ✭✭✭✭

    @ColeX So how do I detect if the user has pressed cancel or sign out? I would normally design xaml with RgpopUp and control it with buttons. But I don't know how to do it here.Because using Command Parameters.

  • dejldejl Member ✭✭
    edited February 10

    @Hamittirpan have you managed to place items at the bottom?

    I've tried to calculate top margin depending on the screen height and the height of other elements but I can't calculate it reliably for iPhone 11.

  • TimothyEntTimothyEnt Member

    Hi all

    So I battled with this for day and found the following solution.

    Mine was an android solution but the principle would work for iOS.

    So in my MainActivity.cs I have the following code.

    var scale = Resources.DisplayMetrics.Density;//density i.e., pixels per inch or cms  
            Resources res = Resources;
            int resourceId = res.GetIdentifier("status_bar_height", "dimen", "android");
            int statusBarHeightPixels = (int)res.GetDimensionPixelSize(resourceId);
            var statusBarHeight = (int)((statusBarHeightPixels - 0.5f) / scale);
            var heightPixels = Resources.DisplayMetrics.HeightPixels;////getting the height in pixels  
            var height = (int)((heightPixels - 0.5f) / scale);//height in units
            Xamarin.Essentials.SecureStorage.SetAsync("toolBarHeight", ((int)(height - statusBarHeight)).ToString());
    

    So you get the height of the screen relative to the pixel density.
    Take off the status bar (where your battery life is).
    Assign it to a variable so other classes can see it (FYI have used cacheStorage before without all the silly casting which I will implement later).

    Cool so you know the screen size!

    Then you need to create a placeholder content view like so. I have a folder called controls that I add my content views too.

    <?xml version="1.0" encoding="utf-8" ?>

    <ContentView.Content>

            </Grid>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.5*" />
                    <ColumnDefinition Width="0.5*" />
                </Grid.ColumnDefinitions>
            </Grid>
        </FlexLayout>
    </ContentView.Content>
    

    You're gonna need some code behind like so!

        [XamlCompilation(XamlCompilationOptions.Compile)]
     public partial class PlaceHolder : ContentView
    {
        public PlaceHolder()
        {
            InitializeComponent();
            BindingContext = new PlaceholderViewModel();
        }
    }
    

    That placeholder view model eh?
    Before you do that go to your AppShell.cs and add the following...

    public Dictionary<string, Type> Routes { get; } = new Dictionary<string, Type>();
    
        public AppShell()
        {
            BindingContext = new AppShellViewModel();
            InitializeComponent();
            RegisterRoutes();
            Xamarin.Essentials.SecureStorage.SetAsync("shellMenuItems", Routes.Count.ToString());
        }
    
        void RegisterRoutes()
        {
            Routes.Add("home", typeof(HomePage));
            Routes.Add("about", typeof(AboutPage));
            Routes.Add("login", typeof(LoginPage));
    
            foreach (var item in Routes)
            {
                Routing.RegisterRoute(item.Key, item.Value);
            }
        }
    

    This registers all your routes for your flyout.
    So you've got some routes... cool!

    Back to the placeholder view model.
    So you're gonna need that height attribute and your route count you set earlier like so!

    public class PlaceholderViewModel
    {
    public int ShellWhiteSpace { get; set; }
    public PlaceholderViewModel()
    {
    var v = Xamarin.Essentials.SecureStorage.GetAsync("toolBarHeight").Result;
    var w = Xamarin.Essentials.SecureStorage.GetAsync("shellMenuItems").Result;
    var x = Convert.ToInt32(w);
    var y = Convert.ToInt32(v);
    var z = y - (55 * (x + 1));
    ShellWhiteSpace = z;
    }
    }

    I have global CSS files to syle my XAML files and I've set my Shell Items height to be 55 hence the 55.
    You're gonna need to remove the shell items you're adding from your whitespace total plus the one you're adding to the bottom.

    Back to you AppShell.xaml

    Add a template for MenuItems

    <Shell.MenuItemTemplate>
            <DataTemplate>
                <ContentView>
                    <ContentView.Content>
                        <controls:PlaceHolder></controls:PlaceHolder>
                    </ContentView.Content>
                </ContentView>
            </DataTemplate>
        </Shell.MenuItemTemplate>
    

    Sick!

    Now put that in between your penultimate and last shell item.


    <FlyoutItem.Icon>

    </FlyoutItem.Icon>

    <MenuItem>
    
    </MenuItem>
    
    <FlyoutItem Route="login"
                Title="Log Out">
        <FlyoutItem.Icon>
            <FontImageSource 
                Glyph="&#x000f0343;"
                FontFamily="{StaticResource MaterialFontFamily}"
                Color="{StaticResource NavigationPrimary}"/>
        </FlyoutItem.Icon>
        <ShellContent Route="login"
                      Title="About"
                      ContentTemplate="{DataTemplate local:LoginPage}"/>
    </FlyoutItem>
    

    You've done it sports fans!!!

Sign In or Register to comment.