Содержание
Элемент Shell предоставляет нам всплывающее меню основными элементами которого являются FlyoutItem и MenuItem, а также заголовок (Header) и подвал (Footer). В этой части мы разберемся с тем как добавлять и настраивать различные элементы всплывающего меню Shell.
Элементы всплывающего меню (FlyoutItem)
Элементы FlyoutItem — это дочерние элементы Shell. В предыдущей части мы узнали, что добавление очередной страницы в Shell с использованием элемента ShellContent приводит к неявному преобразованию таких элементов в элементы FlyoutItems. Вместе с этим, мы можем явно определять те элементы меню, которые необходимо показать пользователю. FlyoutItem предоставляет нам следующие свойства для работы:
| Свойство | Тип | Описание |
Flyout |
FlyoutDisplayOptions |
Определяет, как всплывающий элемент и его дочерние элементы отображаются во всплывающем окне. Может принимать следующие значения:
|
Flyout |
ImageSource |
Значок, который используется для элемента. Если это свойство не установлено, по умолчанию ему присваивается значение свойства Icon |
Flyout |
bool |
Определяет будет ли виден элемент в меню |
Is |
bool |
Определяет, выделен ли этот элемент во всплывающем элементе в настоящий момент. |
Is |
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 имеет смысл вручную определять, когда мы планируем сгруппировать несколько элементов меню, используя свойство Flyout. Например, перепишем 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. В отличие от 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.
При необходимости, мы можем украсить наше меню, добавив в него заголовок и нижний колонтитул. Оба эти элемента меню имеют тип 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), которые позволяют отображать в меню любые элементы.


