Содержание
Элемент 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
), которые позволяют отображать в меню любые элементы.