Xamarin.Forms Shell flyout

Автор:

learn.microsoft.com

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

Элементы Flyout в Xamarin

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

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

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

Оболочка имеет неявные операторы преобразования, которые позволяют упростить визуальную иерархию Shell без введения дополнительных представлений в визуальное дерево. Это возможно потому, что подклассифицированный объект 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.

Примечание. Вкладки отображаются, когда FlyoutItem содержит более одного объекта ShellContent.

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

Определение внешнего вида 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 выделен курсивом:

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

Примечание. Shell предоставляет свойства Title и FlyoutIcon в BindingContext шаблона ItemTemplate.

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

Шаблон по умолчанию для FlyoutItem

Шаблон данных по умолчанию, используемый для каждого 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.

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

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

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

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

Пункты меню

Пункты меню могут быть добавлены в всплывающее меню по желанию, и каждый пункт представлен объектом MenuItem. Положение объектов MenuItem во всплывающем окне зависит от порядка их объявления в визуальной иерархии Shell. Поэтому любые объекты 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 выполняет команду 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 курсивом:

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

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

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

Стиль объектов FlyoutItem и MenuItem

Shell включает три класса стилей, которые автоматически применяются к объектам 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.

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

Заголовок всплывающего окна – это содержимое, которое по желанию отображается в верхней части всплывающего окна. Его внешний вид определяется объектом, который можно задать с помощью свойства привязки 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 по умолчанию.
  • Фиксированный – указывает, что выпадающий заголовок остается видимым и неизменным в любое время.
  • Прокрутка – указывает, что выпадающий заголовок прокручивается по мере того, как пользователь прокручивает элементы.
  • CollapseOnScroll – указывает, что при прокрутке элементов выпадающий заголовок сворачивается только до заголовка.
<Shell ...
      FlyoutHeaderBehavior="CollapseOnScroll">
   ...
</Shell>

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

Нижний колонтитул Flyout

Нижний колонтитул – это содержимое, которое по желанию появляется в нижней части флаута. Его внешний вид определяется объектом, который можно установить с помощью свойства привязки 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:

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

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

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

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

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

Фон Flyout

Цвет фона всплывающего окна можно установить с помощью свойства Shell.FlyoutBackgroundColor:

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

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

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

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

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

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

  • AspectFill - обрезать изображение так, чтобы оно заполняло область отображения с сохранением соотношения сторон.
  • AspectFit - буквокс изображения, если требуется, чтобы изображение поместилось в область отображения, с добавлением пустого пространства сверху/снизу или по бокам в зависимости от того, широкое или высокое изображение. Это значение по умолчанию свойства FlyoutBackgroundImageAspect.
  • Заполнить - растягивает изображение, чтобы оно полностью и точно заполнило область отображения. Это может привести к искажению изображения.

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

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

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

Фон Flyout

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

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

В этом примере всплывающий фон окрашен серебряной кистью SolidColorBrush.

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

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

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

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

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

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

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

Вертикальная прокрутка Flyout

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

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

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

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

Порядок вкладок объектов FlyoutItem

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

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

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

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

После определения порядка табуляции нажатие клавиши Tab приводит к циклическому перемещению фокуса по объектам FlyoutItem в порядке возрастания TabIndex и возврату к началу после достижения последнего объекта.

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

Выбор FlyoutItem

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

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

Эквивалентный код на C#, заданный объектом ShellContent с именем aboutItem, выглядит следующим образом:

CurrentItem = aboutItem;

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

Shell.Current.CurrentItem = aboutItem;

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

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

В качестве альтернативы это можно сделать в коде:

Shell.Current.FlyoutIsPresented = false;
Оглавление

Материалы по теме