Поделиться через


NavigationPage

Навигация .NET MAUI.

Пользовательский интерфейс мультиплатформенного приложения .NET (.NET MAUI) NavigationPage обеспечивает иерархическую навигацию, в которой можно перемещаться по страницам, вперед и назад, как это необходимо. NavigationPage обеспечивает навигацию в виде стека Page объектов первого выхода (LIFO).

NavigationPage определяет следующие свойства:

  • BarBackgroundBrushТип , указывает фон панели навигации в видеBrush.
  • BarBackgroundColorColorТип , указывает цвет фона панели навигации.
  • BackButtonTitle( тип string) представляет текст, используемый для кнопки "Назад". Это присоединенное свойство.
  • BarTextColorColorТип , указывает цвет текста на панели навигации.
  • CurrentPagePageТип , представляет страницу, которая находится в верхней части стека навигации. Это свойство доступно только для чтения.
  • HasNavigationBar, тип bool, представляет, присутствует ли панель навигации на панели навигации NavigationPage. Значение по умолчанию этого свойства равно true. Это присоединенное свойство.
  • HasBackButtonboolТип , представляет, включает ли панель навигации кнопку "Назад". Значение по умолчанию этого свойства равно true. Это присоединенное свойство.
  • IconColor( тип Color) определяет цвет фона значка на панели навигации. Это присоединенное свойство.
  • RootPagePageТип , представляет корневую страницу стека навигации. Это свойство доступно только для чтения.
  • TitleIconImageSourceImageSourceТип , определяет значок, представляющий заголовок на панели навигации. Это присоединенное свойство.
  • TitleViewViewТип , определяет представление, которое можно отобразить на панели навигации. Это присоединенное свойство.

Эти свойства поддерживаются объектами BindableProperty, то есть эти свойства можно указывать в качестве целевых для привязки и стилизации данных.

Класс NavigationPage также определяет три события:

  • Pushed вызывается при отправке страницы в стек навигации.
  • Popped вызывается при появлении страницы из стека навигации.
  • PoppedToRoot вызывается при появлении последней не корневой страницы из стека навигации.

Все три события получают NavigationEventArgs объекты, определяющие свойство только для Page чтения, которое извлекает страницу, которая была получена из стека навигации, или только что видимую страницу в стеке.

Предупреждение

NavigationPage несовместим с приложениями оболочки .NET MAUI Shell, и при попытке использовать NavigationPage в приложении оболочки исключение будет вызвано исключение. Дополнительные сведения о приложениях Оболочки см. в разделе Shell.

Выполнение безрежимной навигации

.NET MAUI поддерживает безрежимную навигацию по страницам. Страница без режима остается на экране и остается доступной, пока не перейдете на другую страницу.

Обычно используется для NavigationPage навигации ContentPage по стеку объектов. Когда одна страница переходит в другую, новая страница отправляется в стек и становится активной страницей:

Отправка страницы в стек навигации.

Когда вторая страница возвращается обратно на первую страницу, страница повернута из стека, а новая верхняя страница становится активной:

Появляется страница из стека навигации.

Элемент NavigationPage состоит из панели навигации с активной страницей, отображаемой под панелью навигации. На следующей схеме показаны основные компоненты панели навигации:

Компоненты NavigationPage.

Необязательный значок можно отобразить между кнопкой "Назад" и заголовком.

Методы навигации предоставляются свойством Navigation любых типов, производных от класса Page. Эти методы позволяют отправлять страницы в стек навигации, всплывать страницы из стека и управлять стеком.

Совет

Рекомендуется, чтобы объект NavigationPage заполнялся ContentPage только объектами.

Создание корневой страницы

Приложение, структурированное вокруг нескольких страниц, всегда имеет корневую страницу, которая является первой страницей, добавленной в стек навигации. Это достигается путем создания NavigationPage объекта, аргумент конструктора которого является корневой страницей приложения, и задание результирующего объекта в качестве значения App.MainPage свойства:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new NavigationPage(new MainPage());
    }
}

Приложение, структурированное вокруг нескольких страниц, всегда имеет корневую страницу, которая является первой страницей, добавленной в стек навигации. Это достигается путем создания NavigationPage объекта, аргумент конструктора которого является корневой страницей приложения, и задание результирующего объекта в качестве корневой страницы:Window

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }

    protected override Window CreateWindow(IActivationState? activationState)
    {
        return new Window(new NavigationPage(new MainPage()));
    }    
}

Примечание.

Свойство RootPage объекта NavigationPage предоставляет доступ к первой странице в стеке навигации.

Отправка страниц в стек навигации

На страницу можно перейти, вызвав PushAsync метод в Navigation свойстве текущей страницы:

await Navigation.PushAsync(new DetailsPage());

В этом примере DetailsPage объект передается в стек навигации, где он становится активной страницей.

Примечание.

Метод PushAsync имеет переопределение, включающее bool аргумент, указывающий, следует ли отображать переход страницы во время навигации. Метод PushAsync , который не имеет bool аргумента, включает переход страницы по умолчанию.

Всплывающие страницы из стека навигации

Активная страница может быть порвана из стека навигации, нажав кнопку "Назад " на устройстве, независимо от того, является ли это физической кнопкой на устройстве или кнопкой на экране.

Чтобы программным способом вернуться на предыдущую страницу, PopAsync метод должен вызываться в Navigation свойстве текущей страницы:

await Navigation.PopAsync();

В этом примере текущая страница удаляется из стека навигации, при этом новая верхняя страница становится активной.

Примечание.

Метод PopAsync имеет переопределение, включающее bool аргумент, указывающий, следует ли отображать переход страницы во время навигации. Метод PopAsync , который не имеет bool аргумента, включает переход страницы по умолчанию.

Кроме того, Navigation свойство каждой страницы также предоставляет PopToRootAsync метод, который появляется все, кроме корневой страницы из стека навигации, поэтому корневая страница приложения является активной.

Управление стеком навигации

Свойство Navigation предоставляет Page NavigationStack свойство, из которого можно получить страницы в стеке навигации. Хотя .NET MAUI поддерживает доступ к стеку навигации, свойство предоставляет InsertPageBefore и RemovePage методы для управления стеком путем Navigation вставки страниц или их удаления.

Метод InsertPageBefore вставляет указанную страницу в стек навигации перед указанной существующей страницей, как показано на следующей схеме.

Вставка страницы в стек навигации.

Метод RemovePage удаляет указанную страницу из стека навигации, как показано на следующей схеме.

Удаление страницы из стека навигации.

Вместе эти методы позволяют настроить пользовательский интерфейс навигации, например заменить страницу входа новой страницей после успешного входа.

Выполнение модальной навигации

.NET MAUI поддерживает модальную навигацию по страницам. На модальной странице пользователь должен выполнить отдельную задачу, причем он не может уйти с этой страницы, пока задача не будет выполнена или отменена.

Модальная страница может быть любой из типов страниц, поддерживаемых .NET MAUI. Чтобы отобразить модальную страницу, приложение должно отправить его в модальный стек, где он станет активной страницей:

Отправка страницы в модальный стек.

Чтобы вернуться к предыдущей странице, приложение должно отобразить текущую страницу из модального стека, а новая верхняя страница становится активной:

Всплывающее окно страницы из модального стека.

Методы модальной навигации предоставляются свойством Navigation любых типов, производных от класса Page. Эти методы позволяют отправлять страницы в модальный стек и всплывать страницы из модального стека. Свойство Navigation также предоставляет ModalStack свойство, из которого можно получить страницы в модальном стеке. Однако не существует средств для работы с модальным стеком или перехода к корневой странице модальной навигации. Причина в том, что такие операции поддерживаются не всеми базовыми платформами.

Примечание.

Объект NavigationPage не требуется для выполнения модальной навигации по страницам.

Отправка страниц в модальный стек

Страницу можно изменить, вызвав PushModalAsync метод в Navigation свойстве текущей страницы:

await Navigation.PushModalAsync(new DetailsPage());

В этом примере DetailsPage объект передается в модальный стек, где он становится активной страницей.

Примечание.

Метод PushModalAsync имеет переопределение, включающее bool аргумент, указывающий, следует ли отображать переход страницы во время навигации. Метод PushModalAsync , который не имеет bool аргумента, включает переход страницы по умолчанию.

Всплывающие страницы из модального стека

Активная страница может быть переброщена из модального стека, нажав кнопку "Назад " на устройстве независимо от того, является ли это физической кнопкой на устройстве или кнопкой на экране.

Чтобы программно вернуться на исходную страницу, PopModalAsync метод должен вызываться в Navigation свойстве текущей страницы:

await Navigation.PopModalAsync();

В этом примере текущая страница удаляется из модального стека, при этом новая верхняя страница становится активной.

Примечание.

Метод PopModalAsync имеет переопределение, включающее bool аргумент, указывающий, следует ли отображать переход страницы во время навигации. Метод PopModalAsync , который не имеет bool аргумента, включает переход страницы по умолчанию.

Отключение кнопки "Назад"

В Android вы всегда можете вернуться на предыдущую страницу, нажав стандартную кнопку "Назад " на устройстве. Если модальная страница требует завершения автономной задачи перед выходом из страницы, приложение должно отключить кнопку "Назад ". Для этого можно переопределить метод Page.OnBackButtonPressed модальной страницы.

Передача данных во время навигации

Иногда странице необходимо передать данные другой странице во время навигации. Два стандартных метода для этого передают данные через конструктор страницы и задав новые страницы BindingContext данным.

Передача данных через конструктор страницы

Самый простой способ передачи данных на другую страницу во время навигации — это аргумент конструктора страниц:

Contact contact = new Contact
{
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
};
...
await Navigation.PushModalAsync(new DetailsPage(contact));

В этом примере Contact объект передается в качестве аргумента DetailPageконструктора. Затем Contact объект можно отобразить.DetailsPage

Передача данных через BindingContext

Альтернативный подход для передачи данных на другую страницу во время навигации заключается в настройке новой страницы BindingContext для данных:

Contact contact = new Contact
{
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
};

await Navigation.PushAsync(new DetailsPage
{
    BindingContext = contact  
});

Преимущество передачи данных навигации через страницу BindingContext заключается в том, что новая страница может использовать привязку данных для отображения данных:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyMauiApp.DetailsPage"
             Title="Details">
    <StackLayout>
        <Label Text="{Binding Name}" />
        <Label Text="{Binding Occupation}" />
    </StackLayout>
</ContentPage>

Дополнительные сведения о привязке данных см. в разделе "Привязка данных".

Отображение представлений на панели навигации

Любой MAUI View .NET можно отобразить на панели навигации.NavigationPage Для этого нужно установить присоединенное свойство NavigationPage.TitleView в View. Это присоединенное свойство может быть задано для любого объекта Page, и, когда Page помещается в NavigationPage, NavigationPage будет учитывать значение этого свойства.

В следующем примере показано, как задать присоединенное NavigationPage.TitleView свойство:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NavigationPageTitleView.TitleViewPage">
    <NavigationPage.TitleView>
        <Slider HeightRequest="44"
                WidthRequest="300" />
    </NavigationPage.TitleView>
    ...
</ContentPage>

Эквивалентный код на C# выглядит так:

Slider titleView = new Slider { HeightRequest = 44, WidthRequest = 300 };
NavigationPage.SetTitleView(this, titleView);

В этом примере Slider на панели NavigationPageнавигации панели навигации отображается элемент управления масштабированием.

Внимание

Многие представления не будут отображаться на панели навигации, если не указан размер представления с помощью свойств WidthRequest и HeightRequest.

Так как класс Layout является производным от класса View, присоединенное свойство TitleView можно настроить для отображения класса макета, содержащего несколько представлений. Однако это может привести к вырезке, если представление, отображаемое на панели навигации, больше размера панели навигации по умолчанию. В Android высоту панели навигации можно изменить, задав для привязываемого свойства NavigationPage.BarHeight значение double, представляющее новую высоту.

Также панель навигации можно расширить, если поместить некоторое содержимое на панели навигации, а некоторое — в представление в верхней части страницы таким образом, чтобы цвет совпадал с панелью навигации. Кроме того, в iOS разделительную линию и тень в нижней части панели навигации можно удалить, установив для привязываемого свойства NavigationPage.HideNavigationBarSeparator значение true.

Совет

Свойства BackButtonTitle, Title, TitleIconImageSource и TitleView позволяют определять значения, которые занимают место на панели навигации. Хотя размер панели навигации зависит от платформы и размера экрана, установка всех этих свойств приведет к конфликтам из-за ограничений свободного пространства. Вместо комбинации этих свойств лучше задать желаемый дизайн панели навигации только с помощью свойства TitleView.