Споделяне чрез


Xamarin.Forms Shell flyout

The navigation experience provided by Xamarin.Forms Shell is based on flyouts and tabs. A flyout is the optional root menu for a Shell application, and is fully customizable. It's accessible through an icon or by swiping from the side of the screen. The flyout consists of an optional header, flyout items, optional menu items, and an optional footer:

Screenshot of a Shell annotated flyout

Flyout items

One or more flyout items can be added to the flyout, and each flyout item is represented by a FlyoutItem object. Each FlyoutItem object should be a child of the subclassed Shell object. Flyout items appear at the top of the flyout when a flyout header isn't present.

The following example creates a flyout containing two flyout items:

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:controls="clr-namespace:Xaminals.Controls"
       xmlns:views="clr-namespace:Xaminals.Views"
       x:Class="Xaminals.AppShell">
    <FlyoutItem Title="Cats"
                Icon="cat.png">
       <Tab>
           <ShellContent ContentTemplate="{DataTemplate views:CatsPage}" />
       </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Dogs"
                Icon="dog.png">
       <Tab>
           <ShellContent ContentTemplate="{DataTemplate views:DogsPage}" />
       </Tab>
    </FlyoutItem>
</Shell>

The FlyoutItem.Title property, of type string, defines the title of the flyout item. The FlyoutItem.Icon property, of type ImageSource, defines the icon of the flyout item:

Screenshot of a Shell two page app with flyout items, on iOS and Android

In this example, each ShellContent object can only be accessed through flyout items, and not through tabs. This is because by default, tabs will only be displayed if the flyout item contains more than one tab.

Important

In a Shell application, pages are created on demand in response to navigation. This is accomplished by using the DataTemplate markup extension to set the ContentTemplate property of each ShellContent object to a ContentPage object.

Shell has implicit conversion operators that enable the Shell visual hierarchy to be simplified, without introducing additional views into the visual tree. This is possible because a subclassed Shell object can only ever contain FlyoutItem objects or a TabBar object, which can only ever contain Tab objects, which can only ever contain ShellContent objects. These implicit conversion operators can be used to remove the FlyoutItem and Tab objects from the previous example:

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:controls="clr-namespace:Xaminals.Controls"
       xmlns:views="clr-namespace:Xaminals.Views"
       x:Class="Xaminals.AppShell">
   <ShellContent Title="Cats"
                 Icon="cat.png"
                 ContentTemplate="{DataTemplate views:CatsPage}" />
   <ShellContent Title="Dogs"
                 Icon="dog.png"
                 ContentTemplate="{DataTemplate views:DogsPage}" />
</Shell>

This implicit conversion automatically wraps each ShellContent object in Tab objects, which are wrapped in FlyoutItem objects.

Note

All FlyoutItem objects in a subclassed Shell object are automatically added to the Shell.FlyoutItems collection, which defines the list of items that will be shown in the flyout.

Flyout display options

The FlyoutItem.FlyoutDisplayOptions property configures how a flyout item and its children are displayed in the flyout. This property should be set to a FlyoutDisplayOptions enumeration member:

  • AsSingleItem, indicates that the item will be visible as a single item. This is the default value of the FlyoutDisplayOptions property.
  • AsMultipleItems, indicates that the item and its children will be visible in the flyout as a group of items.

A flyout item for each Tab object within a FlyoutItem can be displayed by setting the FlyoutItem.FlyoutDisplayOptions property to AsMultipleItems:

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:controls="clr-namespace:Xaminals.Controls"
       xmlns:views="clr-namespace:Xaminals.Views"
       FlyoutHeaderBehavior="CollapseOnScroll"
       x:Class="Xaminals.AppShell">

    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
        <Tab Title="Domestic"
             Icon="paw.png">
            <ShellContent Title="Cats"
                          Icon="cat.png"
                          ContentTemplate="{DataTemplate views:CatsPage}" />
            <ShellContent Title="Dogs"
                          Icon="dog.png"
                          ContentTemplate="{DataTemplate views:DogsPage}" />
        </Tab>
        <ShellContent Title="Monkeys"
                      Icon="monkey.png"
                      ContentTemplate="{DataTemplate views:MonkeysPage}" />
        <ShellContent Title="Elephants"
                      Icon="elephant.png"
                      ContentTemplate="{DataTemplate views:ElephantsPage}" />  
        <ShellContent Title="Bears"
                      Icon="bear.png"
                      ContentTemplate="{DataTemplate views:BearsPage}" />
    </FlyoutItem>

    <ShellContent Title="About"
                  Icon="info.png"
                  ContentTemplate="{DataTemplate views:AboutPage}" />    
</Shell>

In this example, flyout items are created for the Tab object that's a child of the FlyoutItem object, and the ShellContent objects that are children of the FlyoutItem object. This occurs because each ShellContent object that's a child of the FlyoutItem object is automatically wrapped in a Tab object. In addition, a flyout item is created for the final ShellContent object, which is automatically wrapped in a Tab object, and then in a FlyoutItem object.

Note

Tabs are displayed when a FlyoutItem contains more than one ShellContent object.

This results in the following flyout items:

Screenshot of flyout containing FlyoutItem objects, on iOS and Android

Define FlyoutItem appearance

The appearance of each FlyoutItem can be customized by setting the Shell.ItemTemplate attached property to a DataTemplate:

<Shell ...>
    ...
    <Shell.ItemTemplate>
        <DataTemplate>
            <Grid ColumnDefinitions="0.2*,0.8*">
                <Image Source="{Binding FlyoutIcon}"
                       Margin="5"
                       HeightRequest="45" />
                <Label Grid.Column="1"
                       Text="{Binding Title}"
                       FontAttributes="Italic"
                       VerticalTextAlignment="Center" />
            </Grid>
        </DataTemplate>
    </Shell.ItemTemplate>
</Shell>

This example displays the title of each FlyoutItem object in italics:

Screenshot of templated FlyoutItem objects, on iOS and Android

Because Shell.ItemTemplate is an attached property, different templates can be attached to specific FlyoutItem objects.

Note

Shell provides the Title and FlyoutIcon properties to the BindingContext of the ItemTemplate.

In addition, Shell includes three style classes, which are automatically applied to FlyoutItem objects. For more information, see Style FlyoutItem and MenuItem objects.

Default template for FlyoutItems

The default DataTemplate used for each FlyoutItem is shown below:

<DataTemplate x:Key="FlyoutTemplate">
    <Grid x:Name="FlyoutItemLayout"
          HeightRequest="{x:OnPlatform Android=50}"
          ColumnSpacing="{x:OnPlatform UWP=0}"
          RowSpacing="{x:OnPlatform UWP=0}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroupList>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor"
                                    Value="{x:OnPlatform Android=#F2F2F2, iOS=#F2F2F2}" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </VisualStateManager.VisualStateGroups>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{x:OnPlatform Android=54, iOS=50, UWP=Auto}" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Image x:Name="FlyoutItemImage"
               Source="{Binding FlyoutIcon}"
               VerticalOptions="Center"
               HorizontalOptions="{x:OnPlatform Default=Center, UWP=Start}"
               HeightRequest="{x:OnPlatform Android=24, iOS=22, UWP=16}"
               WidthRequest="{x:OnPlatform Android=24, iOS=22, UWP=16}">
            <Image.Margin>
                <OnPlatform x:TypeArguments="Thickness">
                    <OnPlatform.Platforms>
                        <On Platform="UWP"
                            Value="12,0,12,0" />
                    </OnPlatform.Platforms>
                </OnPlatform>
            </Image.Margin>
        </Image>
        <Label x:Name="FlyoutItemLabel"
               Grid.Column="1"
               Text="{Binding Title}"
               FontSize="{x:OnPlatform Android=14, iOS=Small}"
               HorizontalOptions="{x:OnPlatform UWP=Start}"
               HorizontalTextAlignment="{x:OnPlatform UWP=Start}"
               FontAttributes="{x:OnPlatform iOS=Bold}"
               VerticalTextAlignment="Center">
            <Label.TextColor>
                <OnPlatform x:TypeArguments="Color">
                    <OnPlatform.Platforms>
                        <On Platform="Android"
                            Value="#D2000000" />
                    </OnPlatform.Platforms>
                </OnPlatform>
            </Label.TextColor>
            <Label.Margin>
                <OnPlatform x:TypeArguments="Thickness">
                    <OnPlatform.Platforms>
                        <On Platform="Android"
                            Value="20, 0, 0, 0" />
                    </OnPlatform.Platforms>
                </OnPlatform>
            </Label.Margin>
            <Label.FontFamily>
                <OnPlatform x:TypeArguments="x:String">
                    <OnPlatform.Platforms>
                        <On Platform="Android"
                            Value="sans-serif-medium" />
                    </OnPlatform.Platforms>
                </OnPlatform>
            </Label.FontFamily>
        </Label>
    </Grid>
</DataTemplate>

This template can be used for as a basis for making alterations to the existing flyout layout, and also shows the visual states that are implemented for flyout items.

In addition, the Grid, Image, and Label elements all have x:Name values and so can be targeted with the Visual State Manager. For more information, see Set state on multiple elements.

Note

The same template can also be used for MenuItem objects.

Replace flyout content

Flyout items, which represent the flyout content, can optionally be replaced with your own content by setting the Shell.FlyoutContent bindable property to an object:

<Shell ...
       x:Name="shell">
    ...
    <Shell.FlyoutContent>
        <CollectionView BindingContext="{x:Reference shell}"
                        IsGrouped="True"
                        ItemsSource="{Binding FlyoutItems}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Label Text="{Binding Title}"
                           TextColor="White"
                           FontSize="Large" />
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Shell.FlyoutContent>
</Shell>

In this example, the flyout content is replaced with a CollectionView that displays the title of each item in the FlyoutItems collection.

Note

The FlyoutItems property, in the Shell class, is a read-only collection of flyout items.

Alternatively, flyout content can be defined by setting the Shell.FlyoutContentTemplate bindable property to a DataTemplate:

<Shell ...
       x:Name="shell">
    ...
    <Shell.FlyoutContentTemplate>
        <DataTemplate>
            <CollectionView BindingContext="{x:Reference shell}"
                            IsGrouped="True"
                            ItemsSource="{Binding FlyoutItems}">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Label Text="{Binding Title}"
                               TextColor="White"
                               FontSize="Large" />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </DataTemplate>
    </Shell.FlyoutContentTemplate>
</Shell>

Important

A flyout header can optionally be displayed above your flyout content, and a flyout footer can optionally be displayed below your flyout content. If your flyout content is scrollable, Shell will attempt to honor the scroll behavior of your flyout header.

Menu items can be optionally added to the flyout, and each menu item is represented by a MenuItem object. The position of MenuItem objects on the flyout is dependent upon their declaration order in the Shell visual hierarchy. Therefore, any MenuItem objects declared before FlyoutItem objects will appear before the FlyoutItem objects in the flyout, and any MenuItem objects declared after FlyoutItem objects will appear after the FlyoutItem objects in the flyout.

The MenuItem class has a Clicked event, and a Command property. Therefore, MenuItem objects enable scenarios that execute an action in response to the MenuItem being tapped.

MenuItem objects can be added to the flyout as shown in the following example:

<Shell ...>
    ...            
    <MenuItem Text="Help"
              IconImageSource="help.png"
              Command="{Binding HelpCommand}"
              CommandParameter="https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell" />    
</Shell>

This example adds a MenuItem object to the flyout, beneath all the flyout items:

Screenshot of flyout containing a MenuItem object, on iOS and Android

The MenuItem object executes an ICommand named HelpCommand, which opens the URL specified by the CommandParameter property in the system web browser.

Note

The BindingContext of each MenuItem is inherited from the subclassed Shell object.

Define MenuItem appearance

The appearance of each MenuItem can be customized by setting the Shell.MenuItemTemplate attached property to a DataTemplate:

<Shell ...>
    <Shell.MenuItemTemplate>
        <DataTemplate>
            <Grid ColumnDefinitions="0.2*,0.8*">
                <Image Source="{Binding Icon}"
                       Margin="5"
                       HeightRequest="45" />
                <Label Grid.Column="1"
                       Text="{Binding Text}"
                       FontAttributes="Italic"
                       VerticalTextAlignment="Center" />
            </Grid>
        </DataTemplate>
    </Shell.MenuItemTemplate>
    ...
    <MenuItem Text="Help"
              IconImageSource="help.png"
              Command="{Binding HelpCommand}"
              CommandParameter="https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell" />  
</Shell>

This example attaches the DataTemplate to each MenuItem object, displaying the title of the MenuItem object in italics:

Screenshot of templated MenuItem objects, on iOS and Android

Because Shell.MenuItemTemplate is an attached property, different templates can be attached to specific MenuItem objects.

Note

Shell provides the Text and IconImageSource properties to the BindingContext of the MenuItemTemplate. You can also use Title in place of Text and Icon in place of IconImageSource which will let you reuse the same template for menu items and flyout items.

The default template for FlyoutItem objects can also be used for MenuItem objects. For more information, see Default template for FlyoutItems.

Style FlyoutItem and MenuItem objects

Shell includes three style classes, which are automatically applied to FlyoutItem and MenuItem objects. The style class names are FlyoutItemLabelStyle, FlyoutItemImageStyle, and FlyoutItemLayoutStyle.

The following XAML shows an example of defining styles for these style classes:

<Style TargetType="Label"
       Class="FlyoutItemLabelStyle">
    <Setter Property="TextColor"
            Value="Black" />
    <Setter Property="HeightRequest"
            Value="100" />
</Style>

<Style TargetType="Image"
       Class="FlyoutItemImageStyle">
    <Setter Property="Aspect"
            Value="Fill" />
</Style>

<Style TargetType="Layout"
       Class="FlyoutItemLayoutStyle"
       ApplyToDerivedTypes="True">
    <Setter Property="BackgroundColor"
            Value="Teal" />
</Style>

These styles will automatically be applied to FlyoutItem and MenuItem objects, without having to set their StyleClass properties to the style class names.

In addition, custom style classes can be defined and applied to FlyoutItem and MenuItem objects. For more information about style classes, see Xamarin.Forms Style Classes.

Flyout header

The flyout header is the content that optionally appears at the top of the flyout, with its appearance being defined by an object that can be set with the Shell.FlyoutHeader bindable property:

<Shell ...>
    <Shell.FlyoutHeader>
        <controls:FlyoutHeader />
    </Shell.FlyoutHeader>
</Shell>

The FlyoutHeader type is shown in the following example:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Xaminals.Controls.FlyoutHeader"
             HeightRequest="200">
    <Grid BackgroundColor="Black">
        <Image Aspect="AspectFill"
               Source="xamarinstore.jpg"
               Opacity="0.6" />
        <Label Text="Animals"
               TextColor="White"
               FontAttributes="Bold"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
    </Grid>
</ContentView>

This results in the following flyout header:

Screenshot of the flyout header

Alternatively, the flyout header appearance can be defined by setting the Shell.FlyoutHeaderTemplate bindable property to a DataTemplate:

<Shell ...>
    <Shell.FlyoutHeaderTemplate>
        <DataTemplate>
            <Grid BackgroundColor="Black"
                  HeightRequest="200">
                <Image Aspect="AspectFill"
                       Source="xamarinstore.jpg"
                       Opacity="0.6" />
                <Label Text="Animals"
                       TextColor="White"
                       FontAttributes="Bold"
                       HorizontalTextAlignment="Center"
                       VerticalTextAlignment="Center" />
            </Grid>            
        </DataTemplate>
    </Shell.FlyoutHeaderTemplate>
</Shell>

By default, the flyout header will be fixed in the flyout while the content below will scroll if there are enough items. However, this behavior can be changed by setting the Shell.FlyoutHeaderBehavior bindable property to one of the FlyoutHeaderBehavior enumeration members:

  • Default – indicates that the default behavior for the platform will be used. This is the default value of the FlyoutHeaderBehavior property.
  • Fixed – indicates that the flyout header remains visible and unchanged at all times.
  • Scroll – indicates that the flyout header scrolls out of view as the user scrolls the items.
  • CollapseOnScroll – indicates that the flyout header collapses to a title only, as the user scrolls the items.

The following example shows how to collapse the flyout header as the user scrolls:

<Shell ...
       FlyoutHeaderBehavior="CollapseOnScroll">
    ...
</Shell>

The flyout footer is the content that optionally appears at the bottom of the flyout, with its appearance being defined by an object that can be set with the Shell.FlyoutFooter bindable property:

<Shell ...>
    <Shell.FlyoutFooter>
        <controls:FlyoutFooter />
    </Shell.FlyoutFooter>
</Shell>

The FlyoutFooter type is shown in the following example:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="Xaminals.Controls.FlyoutFooter">
    <StackLayout>
        <Label Text="Xaminals"
               TextColor="GhostWhite"
               FontAttributes="Bold"
               HorizontalOptions="Center" />
        <Label Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{0:MMMM dd, yyyy}'}"
               TextColor="GhostWhite"
               HorizontalOptions="Center" />
    </StackLayout>
</ContentView>

This results in the following flyout footer:

Screenshot of the flyout footer

Alternatively, the flyout footer appearance can be defined by setting the Shell.FlyoutFooterTemplate property to a DataTemplate:

<Shell ...>
    <Shell.FlyoutFooterTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="Xaminals"
                       TextColor="GhostWhite"
                       FontAttributes="Bold"
                       HorizontalOptions="Center" />
                <Label Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{0:MMMM dd, yyyy}'}"
                       TextColor="GhostWhite"
                       HorizontalOptions="Center" />
            </StackLayout>
        </DataTemplate>
    </Shell.FlyoutFooterTemplate>
</Shell>

The flyout footer is fixed to the bottom of the flyout, and can be any height. In addition, the footer never obscures any menu items.

Flyout width and height

The width and height of the flyout can be customized by setting the Shell.FlyoutWidth and Shell.FlyoutHeight attached properties to double values:

<Shell ...
       FlyoutWidth="400"
       FlyoutHeight="200">
    ...
</Shell>

This enables scenarios such as expanding the flyout across the entire screen, or reducing the height of the flyout so that it doesn't obscure the tab bar.

Flyout icon

By default, Shell applications have a hamburger icon which, when pressed, opens the flyout. This icon can be changed by setting the Shell.FlyoutIcon bindable property, of type ImageSource, to an appropriate icon:

<Shell ...
       FlyoutIcon="flyouticon.png">
    ...       
</Shell>

Flyout background

The background color of the flyout can be set with the Shell.FlyoutBackgroundColor bindable property:

<Shell ...
       FlyoutBackgroundColor="AliceBlue">
    ...
</Shell>

Note

The Shell.FlyoutBackgroundColor can also be set from a Cascading Style Sheet (CSS). For more information, see Xamarin.Forms Shell specific properties.

Alternatively, the background of the flyout can be specified by setting the Shell.FlyoutBackground bindable property to a Brush:

<Shell ...
       FlyoutBackground="LightGray">
    ...
</Shell>

In this example, the flyout background is painted with a light gray SolidColorBrush.

The following example shows setting the flyout background to a LinearGradientBrush:

<Shell ...>
    <Shell.FlyoutBackground>
        <LinearGradientBrush StartPoint="0,0"
                             EndPoint="1,1">
            <GradientStop Color="#8A2387"
                          Offset="0.1" />
            <GradientStop Color="#E94057"
                          Offset="0.6" />
            <GradientStop Color="#F27121"
                          Offset="1.0" />
        </LinearGradientBrush>
    </Shell.FlyoutBackground>
    ...
</Shell>

For more information about brushes, see Xamarin.Forms Brushes.

Flyout background image

The flyout can have an optional background image, which appears beneath the flyout header and behind any flyout items, menu items, and the flyout footer. The background image can be specified by setting the FlyoutBackgroundImage bindable property, of type ImageSource, to a file, embedded resource, URI, or stream.

The aspect ratio of the background image can be configured by setting the FlyoutBackgroundImageAspect bindable property, of type Aspect, to one of the Aspect enumeration members:

  • AspectFill - clips the image so that it fills the display area while preserving the aspect ratio.
  • AspectFit - letterboxes the image, if required, so that the image fits into the display area, with blank space added to the top/bottom or sides depending on whether the image is wide or tall. This is the default value of the FlyoutBackgroundImageAspect property.
  • Fill - stretches the image to completely and exactly fill the display area. This may result in image distortion.

The following example shows setting these properties:

<Shell ...
       FlyoutBackgroundImage="photo.jpg"
       FlyoutBackgroundImageAspect="AspectFill">
    ...
</Shell>

This results in a background image appearing in the flyout, below the flyout header:

Screenshot of a flyout background image

Flyout backdrop

The backdrop of the flyout, which is the appearance of the flyout overlay, can be specified by setting the Shell.FlyoutBackdrop attached property to a Brush:

<Shell ...
       FlyoutBackdrop="Silver">
    ...
</Shell>

In this example, the flyout backdrop is painted with a silver SolidColorBrush.

Important

The FlyoutBackdrop attached property can be set on any Shell element, but will only be applied when it's set on Shell, FlyoutItem, or TabBar objects.

The following example shows setting the flyout backdrop to a LinearGradientBrush:

<Shell ...>
    <Shell.FlyoutBackdrop>
        <LinearGradientBrush StartPoint="0,0"
                             EndPoint="1,1">
            <GradientStop Color="#8A2387"
                          Offset="0.1" />
            <GradientStop Color="#E94057"
                          Offset="0.6" />
            <GradientStop Color="#F27121"
                          Offset="1.0" />
        </LinearGradientBrush>
    </Shell.FlyoutBackdrop>
    ...
</Shell>

For more information about brushes, see Xamarin.Forms Brushes.

Flyout behavior

The flyout can be accessed through the hamburger icon or by swiping from the side of the screen. However, this behavior can be changed by setting the Shell.FlyoutBehavior attached property to one of the FlyoutBehavior enumeration members:

  • Disabled – indicates that the flyout can't be opened by the user.
  • Flyout – indicates that the flyout can be opened and closed by the user. This is the default value for the FlyoutBehavior property.
  • Locked – indicates that the flyout can't be closed by the user, and that it doesn't overlap content.

The following example shows how to disable the flyout:

<Shell ...
       FlyoutBehavior="Disabled">
    ...
</Shell>

Note

The FlyoutBehavior attached property can be set on Shell, FlyoutItem, ShellContent, and page objects, to override the default flyout behavior.

Flyout vertical scroll

By default, a flyout can be scrolled vertically when the flyout items don't fit in the flyout. This behavior can be changed by setting the Shell.FlyoutVerticalScrollMode bindable property to one of the ScrollMode enumeration members:

  • Disabled – indicates that vertical scrolling will be disabled.
  • Enabled – indicates that vertical scrolling will be enabled.
  • Auto – indicates that vertical scrolling will be enabled if the flyout items don't fit in the flyout. This is the default value of the FlyoutVerticalScrollMode property.

The following example shows how to disable vertical scrolling:

<Shell ...
       FlyoutVerticalScrollMode="Disabled">
    ...
</Shell>

FlyoutItem tab order

By default, the tab order of FlyoutItem objects is the same order in which they are listed in XAML, or programmatically added to a child collection. This order is the order in which the FlyoutItem objects will be navigated through with a keyboard, and often this default order is the best order.

The default tab order can be changed by setting the FlyoutItem.TabIndex property, which indicates the order in which FlyoutItem objects receive focus when the user navigates through items by pressing the Tab key. The default value of the property is 0, and it can be set to any int value.

The following rules apply when using the default tab order, or setting the TabIndex property:

  • FlyoutItem objects with a TabIndex equal to 0 are added to the tab order based on their declaration order in XAML or child collections.
  • FlyoutItem objects with a TabIndex greater than 0 are added to the tab order based on their TabIndex value.
  • FlyoutItem objects with a TabIndex less than 0 are added to the tab order and appear before any zero value.
  • Conflicts on a TabIndex are resolved by declaration order.

After defining a tab order, pressing the Tab key will cycle the focus through FlyoutItem objects in ascending TabIndex order, wrapping around to the beginning once the final object is reached.

In addition to setting the tab order of FlyoutItem objects, it may be necessary to exclude some objects from the tab order. This can be achieved with the FlyoutItem.IsTabStop property, which indicates whether a FlyoutItem is included in tab navigation. Its default value is true, and when its value is false the FlyoutItem is ignored by the tab-navigation infrastructure, irrespective if a TabIndex is set.

FlyoutItem selection

When a Shell application that uses a flyout is first run, the Shell.CurrentItem property will be set to the first FlyoutItem object in the subclassed Shell object. However, the property can be set to another FlyoutItem, as shown in the following example:

<Shell ...
       CurrentItem="{x:Reference aboutItem}">
    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
        ...
    </FlyoutItem>
    <ShellContent x:Name="aboutItem"
                  Title="About"
                  Icon="info.png"
                  ContentTemplate="{DataTemplate views:AboutPage}" />
</Shell>

This example sets the CurrentItem property to the ShellContent object named aboutItem, which results in it being selected and displayed. In this example, an implicit conversion is used to wrap the ShellContent object in a Tab object, which is wrapped in a FlyoutItem object.

The equivalent C# code, given a ShellContent object named aboutItem, is:

CurrentItem = aboutItem;

In this example, the CurrentItem property is set in the subclassed Shell class. Alternatively, the CurrentItem property can be set in any class through the Shell.Current static property:

Shell.Current.CurrentItem = aboutItem;

Note

An application may enter a state where selecting a flyout item is not a valid operation. In such cases, the FlyoutItem can be disabled by setting its IsEnabled property to false. This will prevent users from being able to select the flyout item.

FlyoutItem visibility

Flyout items are visible in the flyout by default. However, an item can be hidden in the flyout with the FlyoutItemIsVisible property, and removed from the flyout with the IsVisible property:

  • FlyoutItemIsVisible, of type bool, indicates if the item is hidden in the flyout, but is still reachable with the GoToAsync navigation method. The default value of this property is true.
  • IsVisible, of type bool, indicates if the item should be removed from the visual tree and therefore not appear in the flyout. Its default value is true.

The following example shows hiding an item in the flyout:

<Shell ...>
    <FlyoutItem ...
                FlyoutItemIsVisible="False">
        ...
    </FlyoutItem>
</Shell>

Note

There's also a Shell.FlyoutItemIsVisible attached property, which can be set on FlyoutItem, MenuItem, Tab, and ShellContent objects.

Open and close the flyout programmatically

The flyout can be programmatically opened and closed by setting the Shell.FlyoutIsPresented bindable property to a boolean value that indicates whether the flyout is currently open:

<Shell ...
       FlyoutIsPresented="{Binding IsFlyoutOpen}">
</Shell>

Alternatively, this can be performed in code:

Shell.Current.FlyoutIsPresented = false;