Страницы приложения .NET MAUI. Классы ContentPage и NavigationPage

Классы 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

Страница типа 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

Сразу стоит отметить, что 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>

то получите ошибку:

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

System.InvalidOperationException: «PopToRootAsync is not supported, please use a NavigationPage.»

Всё, что мы можем сделать на этой странице — это перейти снова на DetailPage, изменив обработчик кнопки «Предыдущая страница» на следующий:

private async void Button_Clicked(object sender, EventArgs e)
{
    await Navigation.PopModalAsync();
}

В дальнейшем мы ещё вернемся к навигации в приложениях .NET MAUI и рассмотрим моменты управления стеком навигации, передачи данных страницам и другие не менее интересные вопросы. Пока же нам будет достаточно знать основы работы с NavigationPage и перейти к рассмотрению следующего типа страниц в .NET MAUI.

Итого

Страница типа ContentPage — это основная страница приложения на которой можно располагать какие-либо элементы управления. В свою очередь, NavigationPage предоставляет нам возможность обеспечить навигацию между страницами приложения на основ стека. Используя методы NavigationPage мы можем обеспечить как безрежимную навигацию по страницам, так и модальную навигацию при которой пользователь может переходить только на предыдущую страницу приложения.

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