Содержание
Классы ContentPage
и NavigationPage
, как и прочие страницы, которые мы будем далее рассматривать, являются наследниками класса Page
.
Класс ContentPage
Страницы типа ContentPage
— это основной вид страниц любого приложения .NET MAUI. Когда мы создаем новое приложение, то оно уже содержит несколько страниц этого типа. ContentPage
содержит одно представление, например, какой-либо контейнер компоновки (Grid
, StackLayout
и т.д.) в котором размещаются все прочие элементы управления.
Класс ContentPage
предоставляет нам следующие свойства
Свойство | Тип | Описание |
Content |
View |
Содержимое страницы |
HideSoftInputOnTapped |
bool |
Указывает, будет ли касание в любом месте на странице вызвать скрытие клавиатуры, если она видна на Android, iOS и Mac Catalyst |
С этим типом страниц мы работаем с самого первого знакомства с .NET MAUI, поэтому не будем подробно останавливаться на работе с такими страницами. Отметим только, что при добавлении новой страницы в приложение в Visual Studio создается именно ContentPage
.
Страница типа NavigationPage
обеспечивает иерархическую навигацию, в которой можно перемещаться по страницам, вперед и назад. При этом навигация осуществляется в виде стека объектов Page, то есть, по принципу LIFO (last in, first out, «последним пришёл — первым ушёл»). Тип NavigationPage
предоставляет нам следующие свойства:
Свойство | Тип | Описание |
BarBackground |
Brush |
Фон панели навигации |
BarBackgroundColor |
Color |
Цвет фона панели навигации |
BackButtonTitle |
string |
Текст кнопки «Назад» |
BarTextColor |
Color |
Цвет текста на панели навигации |
CurrentPage |
Page |
Представляет страницу, которая находится в верхней части стека навигации. Свойство только для чтения. |
HasNavigationBar |
bool |
Определяет отображается ли панель навигации. Значение по умолчанию true |
HasBackButton |
bool |
Определяет отображается ли кнопка «Назад» на панели навигации |
IconColor |
Color |
Цвет фона иконки на панели навигации |
RootPage |
Page |
Представляет корневую страницу стека навигации. Свойство только для чтения |
TitleIconImageSource |
ImageSource |
Иконка панели навигации |
TitleView |
View |
Представление на панели навигации. Можно использовать для размещения на панели навигации собственных элементов управления |
Сразу стоит отметить, что NavigationPage
не поддерживает непосредственное содержимое. То есть, если вы создадите новое приложение .NET MAUI и попробуете изменить тип главной страницы, например, так:
<?xml version="1.0" encoding="utf-8" ?> <NavigationPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MauiApp7.MainPage"> </NavigationPage>
то получите ошибку:
Приложение, работа которого строится вокруг использования нескольких страниц (обычно — это ContentPage
) всегда имеет корневую страницу. То есть такую страницу, которую первой видит пользователь при запуске приложение и которая первой попадает в стек навигации. Чтобы добавить корневую страницу в стек навигации мы должны создать объект типа NavigationPage
, используя конструктор с одним параметром — объектом корневой страницы. Рассмотрим этот момент подробнее.
Итак, создадим новое приложение .NET MAUI, перейдем в файл отдельного кода App.xaml.cs и изменим его следующим образом:
namespace NaviPages { public partial class App : Application { public App() { InitializeComponent(); } protected override Window CreateWindow(IActivationState? activationState) { return new Window(new NavigationPage(new MainPage())); } } }
Здесь мы создали объект NavigationPage
и передали в качестве корневой страницы страницу MainPage
. Если теперь запустить приложение то мы увидим станицы приложения без каких-либо панелей управления.
Теперь добавим в приложение ещё одну страницу. Для этого нажмем правой кнопкой мыши на названии нашего проекта и выберем пункт «Добавить — Создать элемент»
В открывшемся окне выберем «.NET MAUI ContentPage (XAML) (Майкрософт)»
Назовем нашу страницу «DetailPage.xaml». На новой странице определим заголовок
Title
:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NaviPages.DetailPage" Title="Детали"> <VerticalStackLayout> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>
Теперь, чтобы перейти на новую страницу, добавим на страницу MainPage кнопку:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NaviPages.MainPage" Title="Главная страница"> <ScrollView> <VerticalStackLayout> <Button Text="Детали" Clicked="Button_Clicked" /> </VerticalStackLayout> </ScrollView> </ContentPage>
и напишем в файле отдельного кода следующий обработчик клика по кнопке:
namespace NaviPages { public partial class MainPage : ContentPage { int count = 0; public MainPage() { InitializeComponent(); } //обработчик Click private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PushAsync(new DetailPage()); } } }
Теперь запустим приложение и кликнем по кнопке. Вы увидите страницу «Детали», а также кнопку назад:
Для того, чтобы перейти на новую страницу мы воспользовались методом свойства Navigataion
public Task PushAsync(Page page);
который в качестве параметра принимает страницу, которую необходимо поместить в стек навигации. Если кликнуть по кнопке «Назад», то мы снова вернемся на главную страницу приложения. Рассмотрим другие методы управления навигацией, которые мы можем использовать в нашем приложении.
Методы безрежимной навигации
При безрежимной навигации пользователь может выполнить или отменить выполнение какой-либо задачи на странице или же просто нажать кнопку «Назад» и вернуться на предыдущую страницу. Объект Navigation
предоставляет нам следующие методы для навигации:
Метод | Описание |
public Task PushAsync(Page page); |
Асинхронно помещается указанную в параметрах страницу page в стек навигации. Параметр animated указывает на использование необязательной анимации при переходе |
public Task PushAsync(Page page, bool animated); |
|
public Task<Page> PopAsync(bool animated); |
Асинхронно извлекает верхнюю страницу из стека навигации. Параметр animated указывает на использование необязательной анимации при переходе |
public Task<Page> PopAsync(); |
|
public Task PopToRootAsync(bool animated); |
Асинхронно извлекает все страницы из стека навигации (осуществляет переход на корневую страницу). Параметр animated указывает на использование необязательной анимации при переходе |
public Task PopToRootAsync(); |
Используя эти методы, мы можем управлять стеком навигации — помещать страницы в стек (переходить на страницы) или удалять их из стека (закрывать текущую страницу и переходить на предыдущую).
Например, добавим в наше приложение ещё одну страницу, назовем её SecondDetail
и изменим её код следующим образом:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NaviPages.SecondDetail" Title="SecondDetail" NavigationPage.HasBackButton="false"> <VerticalStackLayout> <Button Text="Предыдущая страница" Clicked="Button_Clicked"/> <Button Text="Главная страница" Clicked="Button_Clicked_1"/> </VerticalStackLayout> </ContentPage>
Обработчики событий Click
кнопок будут следующими:
namespace NaviPages; public partial class SecondDetail : ContentPage { public SecondDetail() { InitializeComponent(); } private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PopAsync(); } private async void Button_Clicked_1(object sender, EventArgs e) { await Navigation.PopToRootAsync(); } }
То есть мы предоставляем пользователю возможность либо перейти на одну страницу назад, либо вернуться на главную страницу. Обратите внимание на разметку XAML страницы — здесь мы воспользовались свойством NavigationPage
и скрываем от пользователя кнопку «Назад»
NavigationPage.HasBackButton="false"
Теперь, чтобы продемонстрировать работу со стеком навигации, добавим на страницу DetailPage
кнопку:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NaviPages.DetailPage" Title="Детали" NavigationPage.BackButtonTitle="Венуться" NavigationPage.HasBackButton="True"> <VerticalStackLayout> <Label Text="Welcome to .NET MAUI!" VerticalOptions="Center" HorizontalOptions="Center" /> <Button Text="SecondDetail" Clicked="Button_Clicked"/> </VerticalStackLayout> </ContentPage>
и добавим обработчик Button_Clicked
:
private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PushAsync(new SecondDetail()); }
для перехода на страницу SecondDetail
. Теперь, если пользователь решат добраться до страницы SecondDetail, то будет получен следующий стек навигации:
- При запуске приложения корневой страницей становится
MainPage
. - Как только пользователь нажимает кнопку «Детали», то на вершину стека помещается страница DetailPage
- Если пользователь, находясь на страницу
DetailPage
нажмет кнопку «SecondDetail», то на вершину стека уже будет помещена страницаSecondDetail
- Далее пользователь, используя кнопки, может либо перейти на страницу назад, то есть снова на страницу «Детали», либо перейти на корневую страницу
MainPage
Вот так будет выглядеть последняя страница в стеке навигации — SecondDetail:Обратите внимание на то, что кнопки «Назад» на этой странице нет так как мы её отключили, используя свойство
NavigationPage
.
Методы модальной навигации
В приложении бывает необходимо, чтобы пользователь, перейдя на определенную страницу обязательно выполнил или отменил выполнение операции и, при этом, ему было бы запрещено пользоваться кнопкой «Назад». Для такой работы мы можем использовать методы модальной навигации при выполнении которых пользователю показывается модальное окно в котором отсутствует панель навигации.
Метод | Описание |
public Task PushModalAsync(Page page); |
Асинхронно помещается указанную в параметрах страницу page в стек модальной навигации. Параметр animated указывает на использование необязательной анимации при переходе |
public Task PushModalAsync(Page page, bool animated); |
|
public Task<Page> PopModalAsync(bool animated); |
Асинхронно извлекает верхнюю страницу из стека модальной навигации. Параметр animated указывает на использование необязательной анимации при переходе |
public Task<Page> PopModalAsync(); |
Обратите внимание на то, что при модальной навигации у нас нет метода извлечения всех страниц из стека. С модальной страницы мы можем перейти только обратно на вызывающую страницу. Например, измените обработчик Button_Clicked
на странице DetailPage
следующим образом:
private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PushModalAsync(new SecondDetail()); }
и перейдите на страницу SeconDetail. Вот как она будет выглядеть при помещении в стек модальной навигации:Соответственно, при попытке перейти на главную страницу будет получена ошибка:
Всё, что мы можем сделать на этой странице — это перейти снова на DetailPage
, изменив обработчик кнопки «Предыдущая страница» на следующий:
private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PopModalAsync(); }
В дальнейшем мы ещё вернемся к навигации в приложениях .NET MAUI и рассмотрим моменты управления стеком навигации, передачи данных страницам и другие не менее интересные вопросы. Пока же нам будет достаточно знать основы работы с NavigationPage
и перейти к рассмотрению следующего типа страниц в .NET MAUI.
Итого
Страница типа ContentPage
— это основная страница приложения на которой можно располагать какие-либо элементы управления. В свою очередь, NavigationPage
предоставляет нам возможность обеспечить навигацию между страницами приложения на основ стека. Используя методы NavigationPage
мы можем обеспечить как безрежимную навигацию по страницам, так и модальную навигацию при которой пользователь может переходить только на предыдущую страницу приложения.