Поделиться через


Всплывающий элемент оболочки Xamarin.Forms

Пользовательский интерфейс навигации, предоставляемый оболочкой Xamarin.Forms, основан на всплывающих окнах и вкладках. Всплывающее окно является необязательным корневым меню для приложения оболочки и является полностью настраиваемым. Чтобы открыть всплывающее окно, нажмите соответствующий значок или проведите пальцем от края экрана. Всплывающий элемент состоит из входящих в него пунктов, а также (необязательно) заголовка, пунктов меню и нижнего колонтитула:

Снимок экрана со всплывающим меню и заметками в оболочке

Элементы всплывающего меню

Во всплывающее меню можно добавить один или несколько пунктов, и каждый пункт будет представлен объектом FlyoutItem. Каждый объект FlyoutItem должен быть дочерним для объекта Shell. Если заголовок всплывающего меню отсутствует, элементы всплывающего меню отображаются от самого верха всплывающего меню.

В следующем примере создается всплывающий элемент, содержащее два пункта:

<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>

Свойство FlyoutItem.Title типа string определяет заголовок всплывающего элемента. Свойство FlyoutItem.Icon типа ImageSource определяет значок всплывающего элемента:

Снимок экрана двухстраничного приложения оболочки с элементами всплывающего меню для iOS и Android

В этом примере каждый объект ShellContent доступен только через элементы всплывающего меню, а не через вкладки: Это связано с тем, что по умолчанию вкладки отображаются только в случае, если всплывающий элемент содержит более одной вкладки.

Внимание

В приложении оболочки страницы создаются по запросу в ответ на навигацию. Это достигается с помощью расширения разметки DataTemplate для задания свойства ContentTemplate каждого объекта ShellContent в соответствии с объектом ContentPage.

Оболочка содержит операторы неявного преобразования, которые позволяют упростить визуальную иерархию оболочки без добавления новых представлений в визуальное дерево. Это возможно, поскольку производный объект Shell может содержать только объекты FlyoutItem или объект TabBar, которые могут содержать только объекты Tab, которые, в свою очередь, могут содержать только объекты ShellContent. Эти операторы неявного преобразования позволяют удалить из предыдущего примера объекты FlyoutItem и Tab:

<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>

Это неявное преобразование автоматически заключает каждый объект ShellContent в объекты Tab, которые заключаются в объекты FlyoutItem.

Примечание.

Все объекты FlyoutItem в подклассах объекта Shell добавляются в коллекцию Shell.FlyoutItems, которая определяет список элементов, отображаемых во всплывающем меню.

Параметры отображения всплывающего меню

Свойство FlyoutItem.FlyoutDisplayOptions определяет, как всплывающий элемент и его дочерние элементы отображаются во всплывающем окне. Этому свойству должен быть присвоен член перечисления FlyoutDisplayOptions:

  • AsSingleItem указывает, будет ли элемент отображаться как один элемент; Это значение по умолчанию для свойства FlyoutDisplayOptions.
  • AsMultipleItems указывает, что сам элемент и его дочерние элементы будут отображаться во всплывающем меню как группа элементов.

Всплывающий элемент для каждого объекта Tab в FlyoutItem можно отобразить путем присвоения свойству FlyoutItem.FlyoutDisplayOptions значения 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>

В этом примере элементы всплывающего меню создаются для объекта Tab, производного от объекта FlyoutItem, и объектов ShellContent, производных от объекта FlyoutItem. Это связано с тем, что каждый объект ShellContent, производный от объекта FlyoutItem, автоматически упаковывается в объект Tab. Кроме того, элемент всплывающего меню создается для последнего объекта ShellContent, который автоматически упаковывается в объект Tab, а затем в объект FlyoutItem.

Примечание.

Если элемент FlyoutItem содержит более одного объекта ShellContent, отображаются вкладки.

Все это создает такие элементы всплывающего меню:

Снимок экрана всплывающего меню с объектами FlyoutItem для iOS и Android

Определение внешнего вида FlyoutItem

Внешний вид каждого объекта FlyoutItem можно настроить, присвоив присоединенному свойству Shell.ItemTemplate значение 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>

Этот пример отображает заголовок каждого объекта FlyoutItem курсивом:

Снимок экрана шаблонных объектов FlyoutItem для iOS и Android

Поскольку Shell.ItemTemplate является присоединенным свойством, для отдельных объектов FlyoutItem можно задавать разные шаблоны.

Примечание.

Оболочка предоставляет свойства Title и FlyoutIcon для BindingContext в ItemTemplate.

Кроме того, оболочка содержит три класса стилей, которые автоматически применяются к объектам FlyoutItem. Дополнительные сведения см. в разделе Объекты FlyoutItem и MenuItem.

Шаблон по умолчанию для элементов FlyoutItem

Ниже показан DataTemplate по умолчанию, используемый для каждого элемента FlyoutItem.

<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>

Этот шаблон можно использовать в качестве основы для внесения изменений в существующий макет раскрывающегося меню, а также для отображения визуальных состояний, реализованных для элементов всплывающего меню.

Кроме того, все элементы Grid, Image и Label имеют значения x:Name и поэтому могут использоваться с диспетчером визуальных состояний. Дополнительные сведения см. в разделе Задание состояния для нескольких элементов.

Примечание.

Этот же шаблон можно использовать для объектов MenuItem.

Замена содержимого всплывающего меню

Элементы всплывающего меню, представляющие содержимое всплывающего меню, при необходимости можно заменить собственным содержимым, задав значение object для привязываемого свойства Shell.FlyoutContent:

<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>

В этом примере содержимое всплывающего меню заменяется содержимым CollectionView, в котором отображается заголовок каждого элемента в коллекции FlyoutItems.

Примечание.

Свойство FlyoutItems в классе Shell — это доступная только для чтения коллекция элементов всплывающего меню.

Содержимое всплывающего меню также можно определить, задав значение DataTemplate для привязываемого свойства Shell.FlyoutContentTemplate:

<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>

Внимание

При желании заголовок всплывающего меню можно отобразить над содержимым всплывающего меню, а нижний колонтитул всплывающего меню — под содержимым всплывающего меню. Если содержимое всплывающего меню поддерживает прокрутку, то оболочка попытается обработать поведение прокрутки для заголовка всплывающего меню.

Пункты меню можно при необходимости добавить во всплывающее меню, и каждый пункт будет представлен объектом MenuItem. Положение объектов MenuItem во всплывающем элементе зависит от порядка их объявления в визуальной иерархии оболочки. Таким образом, все объекты MenuItem, объявленные перед объектами FlyoutItem, будут отображаться перед объектами FlyoutItem во всплывающем элементе, а все объекты MenuItem, объявленные после объектов FlyoutItem, будут отображаться после объектов FlyoutItem во всплывающем элементе.

Класс MenuItem имеет событие Clicked и свойство Command. Это означает, что объекты MenuItem позволяют выполнять действия в ответ на касание MenuItem.

Объекты MenuItem можно добавить в всплывающее окно, как показано в следующем примере:

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

Этот пример добавляет объект MenuItem во всплывающее меню под всеми всплывающими элементами:

Снимок экрана всплывающего меню с объектами MenuItem для iOS и Android

Объект MenuItem выполняет ICommand с именем HelpCommand, который открывает в веб-браузере URL-адрес, заданный свойством CommandParameter.

Примечание.

BindingContext для каждого элемента MenuItem наследуется от производного объекта Shell.

Определение внешнего вида MenuItem

Внешний вид каждого объекта MenuItem можно настроить, присвоив присоединенному свойству Shell.MenuItemTemplate значение 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>

В этом примере DataTemplate задается для каждого объекта MenuItem, чтобы заголовок каждого объекта MenuItem отображался курсивом:

Снимок экрана шаблонных объектов MenuItem для iOS и Android

Поскольку Shell.MenuItemTemplate является присоединенным свойством, для отдельных объектов MenuItem можно задавать разные шаблоны.

Примечание.

Оболочка предоставляет свойства Text и IconImageSource для BindingContext в MenuItemTemplate. Можно также использовать Title вместо Text и Icon вместо IconImageSource, что позволяет повторно использовать один и тот же шаблон для пунктов меню и пунктов всплывающего элемента.

Шаблон по умолчанию для объектов FlyoutItem можно также использовать для объектов MenuItem. Дополнительные сведения см. в разделе Шаблон по умолчанию для элементов FlyoutItem.

Объекты Style FlyoutItem и MenuItem

Оболочка включает три класса стилей, которые автоматически применяются к объектам FlyoutItem и MenuItem. Классам стилей заданы следующие имена: FlyoutItemLabelStyle, FlyoutItemImageStyle и FlyoutItemLayoutStyle.

В следующем коде XAML показан пример определения стилей для этих классов стилей:

<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>

Эти стили будут автоматически применены к объектам FlyoutItem и MenuItem, причем задавать их свойствам StyleClass имена классов стилей не требуется.

Кроме того, для объектов FlyoutItem и MenuItem можно определить и применить пользовательские классы стилей. Дополнительные сведения о классах стилей см. в статье Классы стилей Xamarin.Forms.

Заголовок всплывающего меню

Заголовок всплывающего меню — это содержимое, которое при необходимости отображается в верхней части панели; его внешний вид, определяемый object, можно задать с помощью привязываемого свойства Shell.FlyoutHeader:

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

Тип FlyoutHeader показан в примере ниже.

<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>

Вот результат его применения к заголовку всплывающего меню:

Снимок экрана с заголовком всплывающего меню

Кроме того, вид заголовка всплывающего меню можно определить через привязываемое свойство Shell.FlyoutHeaderTemplate, присвоив ему значение 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>

По умолчанию заголовок всплывающего меню будет зафиксирован во всплывающем элементе, хотя приведенное ниже его содержимое прокручивается в том случае, если элементов много. Тем не менее это поведение можно изменить, задав в привязываемом свойстве Shell.FlyoutHeaderBehavior один из членов перечисления FlyoutHeaderBehavior:

  • Default означает, что для полос прокрутки будет использоваться поведение, установленное для платформы по умолчанию. Это значение по умолчанию для свойства FlyoutHeaderBehavior.
  • Fixed означает, что заголовок всплывающего меню все время остается видимым и не изменяется.
  • Scroll указывает, что заголовок всплывающего меню пропадает с экрана, прокручиваясь вместе с другими элементами.
  • CollapseOnScroll указывает, что заголовок всплывающего меню сворачивается до заглавия во время прокрутки элементов.

В следующем примере показано, как свернуть заголовок всплывающего меню при прокрутке пользователем:

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

Нижний колонтитул всплывающего меню — это содержимое, которое при необходимости отображается в нижней части элемента. Его внешний вид, определяемый в object, можно задать с помощью привязываемого свойства Shell.FlyoutFooter:

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

Тип FlyoutFooter показан в примере ниже.

<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>

В результате получается нижний колонтитул следующего вида:

Снимок экрана нижнего колонтитула всплывающего меню

Кроме того, вид нижнего колонтитула всплывающего меню можно определить через свойство Shell.FlyoutFooterTemplate для 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>

Нижний колонтитул фиксируется в нижней части всплывающего окна и может иметь любую высоту. Кроме того, нижний колонтитул меню никогда не скрывает никаких его пунктов.

Ширина и высота всплывающего меню

Ширину и высоту всплывающего меню можно настроить, установив для присоединенных свойств Shell.FlyoutWidth и Shell.FlyoutHeight значение double:

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

Это позволяет выполнять такие сценарии как расширение всплывающего меню по всему экрану или уменьшение высоты всплывающего меню, чтобы оно не закрывало панель вкладок.

Значок всплывающего меню

По умолчанию приложения оболочки оснащаются значком "гамбургера", при нажатии которого открывается всплывающее меню. Вы можете изменить этот значок, присвоив привязываемому свойству Shell.FlyoutIcon с типом ImageSource значение, соответствующее нужному значку:

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

Фон всплывающего элемента

Задать цвет фона всплывающего элемента можно с помощью привязываемого свойства Shell.FlyoutBackgroundColor.

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

Примечание.

Свойство Shell.FlyoutBackgroundColor также можно задать из каскадной таблицы стилей (CSS). Подробные сведения см. в разделе Особые свойства оболочки Xamarin.Forms.

Кроме того, можно указать фон всплывающего элемента, задав привязываемому свойству Shell.FlyoutBackground значение Brush.

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

В этом примере для фона всплывающего элемента выбран светло-серый цвет (SolidColorBrush).

В следующем примере показано, что для фона всплывающего элемента задано 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>

Дополнительные сведения о кистях см. в статье Кисти Xamarin.Forms.

Фоновое изображение всплывающего элемента

Всплывающий элемент может иметь необязательное фоновое изображение, которое отображается под заголовком всплывающего элемента, а также за всеми всплывающими элементами, пунктами меню и нижним колонтитулом. Фоновое изображение можно указать, задав для привязываемого свойства FlyoutBackgroundImage типа ImageSource файл, внедренный ресурс, URI или поток.

Пропорции фонового изображения можно настроить, установив для привязываемого свойства FlyoutBackgroundImageAspect типа Aspect один из членов перечисления Aspect:

  • AspectFill — обрезает изображение таким образом, чтобы оно заполнило область экрана, сохраняя пропорции.
  • AspectFit — осуществляет леттербоксинг изображения (при необходимости), чтобы изображение поместилось в область экрана, с добавлением пустого пространства в верхнюю, нижнюю или боковую часть в зависимости от ориентации изображения. Это значение по умолчанию для свойства FlyoutBackgroundImageAspect.
  • Fill — растягивает изображение, чтобы полностью заполнить отображаемую область. Это может привести к искажению изображения.

В следующем примере показано задание этих свойств:

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

Это приводит к отображению фонового изображения во всплывающем элементе под заголовком:

Снимок экрана: фоновое изображение всплывающего элемента

фон всплывающего элемента

Фон всплывающего элемента (внешний вид наложения всплывающего окна) можно указать, задав для Shell.FlyoutBackdrop присоединенное свойство Brush:

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

В этом примере для фона всплывающего элемента выбран серебряный цвет (SolidColorBrush).

Внимание

Присоединенное свойство FlyoutBackdrop можно задать для любого элемента оболочки, но оно будет применяться только в том случае, если задано для объектов Shell, FlyoutItem или TabBar.

В следующем примере показано, что для фона всплывающего элемента указана кисть 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>

Дополнительные сведения о кистях см. в статье Кисти Xamarin.Forms.

Поведение всплывающего меню

Всплывающее меню отображается, если нажать кнопку "гамбургер" или провести пальцем от края экрана. Но вы можете изменить это поведение, задав в присоединенном свойстве Shell.FlyoutBehavior один из членов перечисления FlyoutBehavior:

  • Disabled указывает, что пользователь не может открывать всплывающее меню;
  • Flyout указывает, что пользователь может открывать и закрывать всплывающее меню. Это значение по умолчанию для свойства FlyoutBehavior.
  • Locked указывает, что пользователь не может закрыть всплывающее меню, и это меню не перекрывает содержимое.

В следующем примере показано, как отключить всплывающее меню.

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

Примечание.

Присоединенному свойству FlyoutBehavior можно присвоить значение Shell, FlyoutItem, ShellContent или объект страницы, чтобы переопределить поведение всплывающего меню по умолчанию.

вертикальная прокрутка всплывающего меню

По умолчанию всплывающее меню можно прокручивать по вертикали, если элементы не помещаются в нем. Это поведение можно изменить, задав в привязываемом свойстве Shell.FlyoutVerticalScrollMode один из элементов перечисления ScrollMode:

  • Disabled — указывает, что вертикальная прокрутка будет отключена.
  • Enabled — указывает, что вертикальная прокрутка будет включена.
  • Auto — указывает, что вертикальная прокрутка будет включена, если элементы не помещаются во всплывающем меню. Это значение по умолчанию для свойства FlyoutVerticalScrollMode.

В следующем примере показано, как отключить вертикальную прокрутку.

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

Последовательность табуляции для FlyoutItem

По умолчанию последовательность табуляции для объектов FlyoutItem соответствует порядку, в котором они перечислены в XAML или программно добавлены в дочернюю коллекцию. Этот порядок определяет порядок навигации по элементам FlyoutItem с клавиатуры, и часто порядок по умолчанию является оптимальным.

Вы можете изменить установленную по умолчанию последовательность табуляции, задав свойство FlyoutItem.TabIndex. Оно обозначает порядок, в котором объекты FlyoutItem будут получать фокус при переходе пользователя между элементами путем нажатия клавиши TAB. По умолчанию свойство равно 0, при этом оно может принимать любое значение int.

Следующие правила применяются при использовании последовательности табуляции по умолчанию или задании свойства TabIndex:

  • Объекты FlyoutItem со значением 0 для свойства TabIndex добавляются в последовательность табуляции в том порядке, в котором они объявлены в XAML или дочерних коллекциях.
  • Объекты FlyoutItem со значением TabIndex больше 0 добавляются в последовательность табуляции с учетом значений TabIndex.
  • Объекты FlyoutItem со значением TabIndex меньше 0 добавляются в последовательность табуляции и отображаются раньше, чем любой объект с нулевым значением.
  • Конфликты для TabIndex устраняются в порядке объявления.

Когда последовательность табуляции определена, нажатие клавиши TAB переключает фокус между объектами FlyoutItem в порядке возрастания значений TabIndex, а после достижения конечного элемента управления возвращает фокус в начало.

Кроме настройки последовательности табуляции для объектов FlyoutItem, может потребоваться исключить из этой последовательности некоторые объекты. Это можно сделать с помощью свойства FlyoutItem.IsTabStop, которое указывает, включается ли FlyoutItem в навигацию по клавише TAB. Значение по умолчанию — true, а если оно равно false, элемент FlyoutItem игнорируется инфраструктурой навигации по клавише TAB, независимо от значения TabIndex.

Выбор FlyoutItem

При первом запуске приложения оболочки, использующего всплывающий элемент, свойству Shell.CurrentItem будет присвоено значение первого объекта FlyoutItem в производном объекте Shell. Но этому свойству можно присвоить значение другого FlyoutItem, как показано в следующем примере:

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

В этом примере объекту ShellContent с именем aboutItem задается свойство CurrentItem, что приводит к его выделению и отображению. В нашем примере используется неявное преобразование для помещения объекта ShellContent в объект Tab, который упаковывается в объект FlyoutItem.

С учетом объекта ShellContent с именем aboutItem эквивалентный код на C# выглядит так:

CurrentItem = aboutItem;

В этом примере свойство CurrentItem задается в подклассе класса Shell. Кроме того, свойство CurrentItem может быть задано в любом классе с помощью статического свойства Shell.Current:

Shell.Current.CurrentItem = aboutItem;

Примечание.

Приложение может ввести состояние, при котором выбор всплывающего элемента не является допустимой операцией. В таких случаях FlyoutItem можно отключить, задав свойству IsEnabled значение false. В результате пользователи не смогут выбрать всплывающий элемент.

Видимость FlyoutItem

По умолчанию элементы всплывающего меню являются видимыми. Однако элемент может быть скрыт во всплывающем меню со свойством FlyoutItemIsVisible и удален из всплывающего окна со свойством IsVisible:

  • FlyoutItemIsVisible типа bool указывает, скрыт ли элемент во всплывающем меню, но по-прежнему доступен с помощью метода навигации GoToAsync. Значение по умолчанию этого свойства равно true.
  • IsVisible типа bool указывает, следует ли удалять элемент из визуального дерева и, следовательно, не отображать во всплывающем окне. Значение по умолчанию — true.

В следующем примере показано скрытие элемента во всплывающем меню:

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

Примечание.

Также имеется присоединенное свойство Shell.FlyoutItemIsVisible, которое можно задать для объектов FlyoutItem, MenuItem, Tab и ShellContent.

Открытие и закрытие всплывающего меню программным способом

Всплывающее меню можно открывать и закрывать программным образом, задавая привязываемому свойству Shell.FlyoutIsPresented значение boolean, которое определяет открытие всплывающего меню на текущий момент:

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

Кроме того, это может быть выполнено в коде:

Shell.Current.FlyoutIsPresented = false;