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:
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:
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 theFlyoutDisplayOptions
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:
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:
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
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:
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:
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:
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 theFlyoutHeaderBehavior
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>
Flyout footer
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:
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 theFlyoutBackgroundImageAspect
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:
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 theFlyoutBehavior
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 theFlyoutVerticalScrollMode
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 aTabIndex
equal to 0 are added to the tab order based on their declaration order in XAML or child collections.FlyoutItem
objects with aTabIndex
greater than 0 are added to the tab order based on theirTabIndex
value.FlyoutItem
objects with aTabIndex
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 typebool
, indicates if the item is hidden in the flyout, but is still reachable with theGoToAsync
navigation method. The default value of this property istrue
.IsVisible
, of typebool
, indicates if the item should be removed from the visual tree and therefore not appear in the flyout. Its default value istrue
.
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;