Shell. Работа с меню (FlyoutItem и MenuItem)

Элемент Shell предоставляет нам всплывающее меню основными элементами которого являются FlyoutItem и MenuItem, а также заголовок (Header) и подвал (Footer). В этой части мы разберемся с тем как добавлять и настраивать различные элементы всплывающего меню Shell.

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

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

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

  • AsSingleItem— значение по умолчанию. Элемент отображается как одиночный
  • AsMultipleItems— указывает, что элемент и его прямые дочерние элементы будут отображаться в меню в виде группы элементов.
FlyoutIcon ImageSource Значок, который используется для элемента. Если это свойство не установлено, по умолчанию ему присваивается значение свойства Icon
FlyoutItemIsVisible bool Определяет будет ли виден элемент в меню
IsChecked bool Определяет, выделен ли этот элемент во всплывающем элементе в настоящий момент.
IsEnabled bool Определяет, доступен ли для выбора в меню данный FlyoutItem
Icon ImageSource Значок пункта меню
Route string Строка, используемая для адресации элемента (URI)
Title string Текст элемента меню

Воспользуемся этими свойствами в приложении.

Здесь и далее в разделе будет использоваться исходный код приложения, которое мы создали в первой части про элемент Shell

Для начала оформим элементы меню в виде элементов FlyoutItem. Для этого перейдем в файл AppShell.xaml и изменим его код следующим образом:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="AppShellEx.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AppShellEx"
    Shell.FlyoutBehavior="Flyout"
    Title="AppShellEx">

    <FlyoutItem Title="Home" FlyoutIcon="id.png" Route="MainPage">
         <ShellContent ContentTemplate="{DataTemplate local:MainPage}"/>
    </FlyoutItem>

    <FlyoutItem Title="Detail" FlyoutIcon="phone.png" Route="Detail">
        <ShellContent ContentTemplate="{DataTemplate local:DetailPage}"/>
    </FlyoutItem>

</Shell>

Здесь мы определили два объекта FlyoutItem, каждому из которых передали свой объект ShellContent. Как и было сказано ранее, ShellContent в .NET MAUI автоматически упаковывается в объект FlyoutItem, поэтому приведенный выше код, по большому счёту, ничего не изменит в нашем приложении — меню также будет содержать два элемента:

При такой работе .NET MAUI, элементы FlyoutItem имеет смысл вручную определять, когда мы планируем сгруппировать несколько элементов меню, используя свойство FlyoutDisplayOptions. Например, перепишем XAML-код для Shell следующим образом:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="AppShellEx.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AppShellEx"
    Shell.FlyoutBehavior="Flyout"
    Title="AppShellEx">

    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
        <Tab Title="Группа элементов" FlyoutDisplayOptions="AsMultipleItems">
            <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainPage}"/>
            <ShellContent Title="Detail" ContentTemplate="{DataTemplate local:DetailPage}"/>
        </Tab>
    </FlyoutItem>

    <FlyoutItem Title="Detail" FlyoutIcon="phone.png" Route="Detail">
        <ShellContent ContentTemplate="{DataTemplate local:DetailPage}"/>
    </FlyoutItem>

</Shell>

Здесь мы, для примера, сгруппировали два элемента меню. Элемент Tab, который мы использовали в первом FlyoutItem — это элемент производный от FlyoutItem. Внешний вид меню будет зависеть от платформы на которой запускается приложение. Так, в Windows наше приложение будет выглядеть следующим образом:

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

В Android сгруппированные элементы меню будут показаны как вкладки вверху страницы:

Элементы меню (MenuItem)

При необходимости, мы можем добавить в меню элементы MenuItem. В отличие от FlyoutItem, у элементов меню определено событие Clicked. Соответственно, для создания элемента меню нам необязательно задействовать какую-либо страницу в приложении. Например, добавим в наше приложение следующий пункт меню:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="AppShellEx.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AppShellEx"
    Shell.FlyoutBehavior="Flyout"
    Title="AppShellEx">

    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
        <Tab Title="Группа элементов" FlyoutDisplayOptions="AsMultipleItems">
            <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainPage}"/>
            <ShellContent Title="Detail" ContentTemplate="{DataTemplate local:DetailPage}"/>
        </Tab>
    </FlyoutItem>

    <FlyoutItem Title="Detail" FlyoutIcon="phone.png" Route="Detail">
        <ShellContent ContentTemplate="{DataTemplate local:DetailPage}"/>
    </FlyoutItem>

    <MenuItem Text="Перейти на сайт" Clicked="MenuItem_Clicked"></MenuItem>
    
</Shell>

У пункта меню мы определили обработчик события Click

<MenuItem Text="Перейти на сайт" Clicked="MenuItem_Clicked"></MenuItem>

Который в файле отдельного кода AppShell.xaml.cs выглядит следующим образом:

private async void MenuItem_Clicked(object sender, EventArgs e)
{
    await Browser.Default.OpenAsync("https://csharp.webdelphi.ru");
}

В приложении этот пункт меню ничем не будет отличаться от уже добавленных элементов (за исключением того, что мы не стали определять для него значок):

При клике по этому пункту меню откроется главная страница этого сайта. Положение пунктов меню зависит от того, как они располагаются в Shell — если пункт меню располагается над FlyoutItem, то и в запущенном приложении он будет расположен над FlyoutItem.

Заголовок (Header) и нижний колонтитул (Footer) меню

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

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="AppShellEx.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AppShellEx"
    Shell.FlyoutBehavior="Flyout"
    Title="AppShellEx">

    <Shell.FlyoutHeader>
        <Label Text="Меню приложения" Margin="10" HorizontalTextAlignment="Center" TextColor="Blue" FontAttributes="Bold"/>
    </Shell.FlyoutHeader>

    <Shell.FlyoutFooter>
        <Button Text="Кнопка в нижнем колонтитуле"></Button>
    </Shell.FlyoutFooter>
    
    
    <FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
        <Tab Title="Группа элементов" FlyoutDisplayOptions="AsMultipleItems">
            <ShellContent Title="Home" ContentTemplate="{DataTemplate local:MainPage}"/>
            <ShellContent Title="Detail" ContentTemplate="{DataTemplate local:DetailPage}"/>
        </Tab>
    </FlyoutItem>

    <FlyoutItem Title="Detail" FlyoutIcon="phone.png" Route="Detail">
        <ShellContent ContentTemplate="{DataTemplate local:DetailPage}"/>
    </FlyoutItem>

    <MenuItem Text="Перейти на сайт" Clicked="MenuItem_Clicked"></MenuItem>
    
</Shell>

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

<Shell.FlyoutHeader>
    <Label Text="Меню приложения" Margin="10" HorizontalTextAlignment="Center" TextColor="Blue" FontAttributes="Bold"/>
</Shell.FlyoutHeader>

а в нижнем колонтитуле — кнопку:

<Shell.FlyoutFooter>
    <Button Text="Кнопка в нижнем колонтитуле"></Button>
</Shell.FlyoutFooter>

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

Стоит отметить, что так как заголовок меню может самое различное количество элементов, которые могут занимать достаточно большое пространство в меню, то у элемента Shell определено свойство FlyoutHeaderBehavior с помощью которого мы можем выбрать поведение заголовка меню:

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

Определить это свойство в нашем приложении можно, например, так:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell ...
    Shell.FlyoutHeaderBehavior ="Fixed">

...    
</Shell>

Итого

Всплывающее меню в .NET MAUI может содержать элементы различных типов: FlyoutItem и MenuItem. У MenuItem помимо свойств текста элемента, иконки и т.д. также определено свойство Clicked. Также меню может содержать такие необязательные элементы как заголовок (Header) и нижний колонтитул (Footer), которые позволяют отображать в меню любые элементы.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии