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


Навигация в оболочке .NET MAUI

Просмотрите пример. Обзор примера

Оболочка Shell в .NET MAUI (.NET Multi-Platform App UI) включает интерфейс навигации на основе URI, в котором маршруты позволяют переходить на любую страницу в приложении без строгого соблюдения иерархии навигации. Кроме того, есть возможность перемещаться в обратном направлении без обязательного посещений всех страниц в стеке навигации.

Класс Shell определяет следующие свойства, связанные с навигацией:

  • BackButtonBehaviorс типом BackButtonBehavior — присоединяемое свойство, которое определяет поведение кнопки "Назад";
  • CurrentItem с типом ShellItem — обозначает текущий выбранный элемент;
  • CurrentPage с типом Page — обозначает текущую отображаемую страницу;
  • CurrentState с типом ShellNavigationState — текущее состояние навигации для Shell;
  • Current с типом Shell —псевдоним Application.Current.MainPage с приведением типа.

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

Навигация выполняется путем вызова метода GoToAsync из класса Shell. Когда планируется действие навигации, срабатывает событие Navigating, а после завершения навигации — событие Navigated.

Примечание.

Навигация по-прежнему может выполняться между страницами в приложении оболочки с помощью Navigation свойства. Дополнительные сведения см. в разделе "Выполнение безрежимной навигации".

Маршруты

Навигация в приложении с оболочкой Shell выполняется путем указания универсального кода ресурса (URI) для перехода. URI навигации могут содержать следующие три компонента:

  • Маршрут, который определяет путь к содержимому в составе визуальной иерархии оболочки Shell.
  • Страница. Страницы, которые отсутствуют в визуальной иерархии оболочки Shell, можно поместить в стек навигации из любого места в приложении. Например, страница сведений отсутствует в визуальной иерархии оболочки Shell, но при необходимости может быть помещена в стек навигации.
  • Один или несколько параметров запроса. Параметры запроса можно передать целевой странице при вызове метода навигации.

Если URI навигации содержит все три компонента, он имеет формат "//маршрут/страница?параметры".

Регистрация маршрутов

Маршруты можно определить для объектов FlyoutItem, TabBar, Tab и ShellContent с помощью свойств Route:

<Shell ...>
    <FlyoutItem ...
                Route="animals">
        <Tab ...
             Route="domestic">
            <ShellContent ...
                          Route="cats" />
            <ShellContent ...
                          Route="dogs" />
        </Tab>
        <ShellContent ...
                      Route="monkeys" />
        <ShellContent ...
                      Route="elephants" />  
        <ShellContent ...
                      Route="bears" />
    </FlyoutItem>
    <ShellContent ...
                  Route="about" />                  
    ...
</Shell>

Примечание.

С каждым элементом в иерархии оболочки сопоставляется маршрут. Если маршрут не задан, он создается во время выполнения. Однако созданные маршруты не гарантируют согласованность между различными сеансами приложений.

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

animals
  domestic
    cats
    dogs
  monkeys
  elephants
  bears
about

Чтобы перейти к объекту ShellContent по маршруту dogs, абсолютный URI должен выглядеть так: //animals/domestic/dogs. Аналогичным образом для перехода к объекта ShellContent по маршруту about абсолютный URI должен выглядеть так: //about.

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

При ArgumentException обнаружении повторяющегося маршрута создается при запуске приложения. Это исключение также будет создаваться, если два или более маршрута на одном уровне иерархии совместно используют имя маршрута.

Регистрация маршрутов страниц сведений

В конструкторе подкласса Shell или в любом другом расположении, которое выполняется перед вызовом маршрута, можно явным образом зарегистрировать дополнительные маршруты для любых страниц подробных сведений, которые отсутствуют в визуальной иерархии оболочки Shell. Это выполняется с помощью метода Routing.RegisterRoute:

Routing.RegisterRoute("monkeydetails", typeof(MonkeyDetailPage));
Routing.RegisterRoute("beardetails", typeof(BearDetailPage));
Routing.RegisterRoute("catdetails", typeof(CatDetailPage));
Routing.RegisterRoute("dogdetails", typeof(DogDetailPage));
Routing.RegisterRoute("elephantdetails", typeof(ElephantDetailPage));

Этот пример регистрирует страницы сведений, для которых не определены маршруты в подклассе Shell. Затем эти страницы сведений можно перейти к использованию навигации на основе URI в любом месте приложения. Маршруты для таких страниц называются глобальными маршрутами.

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

Если метод Routing.RegisterRoute пытается зарегистрировать один и тот же маршрут к двум или более разным типам, будет создано исключение ArgumentException.

Также вы можете регистрировать страницы в другие иерархии маршрутов, если потребуется:

Routing.RegisterRoute("monkeys/details", typeof(MonkeyDetailPage));
Routing.RegisterRoute("bears/details", typeof(BearDetailPage));
Routing.RegisterRoute("cats/details", typeof(CatDetailPage));
Routing.RegisterRoute("dogs/details", typeof(DogDetailPage));
Routing.RegisterRoute("elephants/details", typeof(ElephantDetailPage));

Этот пример настраивает контекстную навигацию по страницам, где переход по маршруту details со страницы для маршрута monkeys отображает MonkeyDetailPage. Аналогичным образом переход по маршруту details со страницы для маршрута elephants отображает ElephantDetailPage. Дополнительные сведения см. в разделе Контекстная навигация.

Примечание.

Если для страницы зарегистрированы маршруты с помощью метода Routing.RegisterRoute, вы можете отменить такую регистрацию с помощью метода Routing.UnRegisterRoute, если потребуется.

Выполнение перемещения

Чтобы выполнить перемещение, нужно получить ссылку на подкласс Shell. Чтобы получить эту ссылку, можно привести свойство App.Current.MainPage к объекту Shell или получить значение свойства Shell.Current. После этого выполняется перемещение путем вызова метода GoToAsync из объекта Shell. Этот метод переходит к ShellNavigationState и возвращает Task, который завершается после завершения анимации для этого перехода. Объект ShellNavigationState создается с помощью метода GoToAsync из string или Uri и для его свойства Location задается значение аргумента string или Uri.

Внимание

При переходе по маршруту, входящему в визуальную иерархию оболочки, стек навигации не создается. Но при переходе к странице, которая не входит в визуальную иерархию оболочки, создается стек навигации.

Текущее состояние навигации для объекта Shell можно извлечь через свойство Shell.Current.CurrentState, которое содержит URI отображаемого маршрута в свойстве Location.

Абсолютные маршруты

Для навигации можно передать допустимый абсолютный URI в качестве аргумента в метод GoToAsync:

await Shell.Current.GoToAsync("//animals/monkeys");

Этот пример выполняет переход на страницу с маршрутом monkeys, который определен в объекте ShellContent. Объект ShellContent, который представляет маршрут monkeys, является дочерним элементом объекта FlyoutItem с маршрутом animals.

Относительные маршруты

Для навигации можно также передать допустимый относительный URI в качестве аргумента в метод GoToAsync. Система маршрутизации попытается сопоставить URI с объектом ShellContent. Таким образом, если все маршруты в приложении уникальны, навигация может выполняться только путем указания уникального имени маршрута в качестве относительного URI.

Поддерживаются следующие форматы относительных маршрутов.

Формат Description
маршрут Поиск указанного маршрута выполняется в иерархии маршрутов вверх, начиная от текущей позиции. Страница совпадения будет отправлена в стек навигации.
/маршрут Поиск указанного маршрута выполняется в иерархии маршрутов вниз, начиная от текущей позиции. Страница совпадения будет отправлена в стек навигации.
//маршрут Поиск указанного маршрута выполняется в иерархии маршрутов вверх, начиная от текущей позиции. Страница совпадения заменит стек навигации.
///маршрут Поиск указанного маршрута выполняется в иерархии маршрутов вниз, начиная от текущей позиции. Страница совпадения заменит стек навигации.

В приведенном ниже примере выполняется переход на страницу с маршрутом monkeydetails.

await Shell.Current.GoToAsync("monkeydetails");

В этом примере поиск маршрута в иерархии monkeyDetails выполняется вверх до тех пор, пока не будет найдена станица совпадения. Найденная страница отправляется в стек навигации.

Контекстная навигация

Относительные маршруты позволяют организовать контекстную навигацию. Для примера рассмотрим следующую иерархию маршрутов:

monkeys
  details
bears
  details

Когда отображается страница с зарегистрированным маршрутом monkeys, переход по маршруту details отображает страницу с зарегистрированным маршрутом monkeys/details. Аналогичным образом, когда отображается страница с зарегистрированным маршрутом bears, переход по маршруту details отображает страницу с зарегистрированным маршрутом bears/details. Сведения о том, как зарегистрировать маршруты для этого примера, см. в этой статье.

Обратная навигация

Обратную навигацию можно выполнить, указав аргумент ".." в вызове метода GoToAsync:

await Shell.Current.GoToAsync("..");

Обратную навигацию с ".." можно также объединить с маршрутом:

await Shell.Current.GoToAsync("../route");

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

Внимание

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

Аналогичным образом можно перемещаться назад несколько раз, а затем переходить по указанному маршруту:

await Shell.Current.GoToAsync("../../route");

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

Кроме того, при обратной навигации можно передавать данные в свойствах запроса:

await Shell.Current.GoToAsync($"..?parameterToPassBack={parameterValueToPassBack}");

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

Примечание.

Параметры запроса можно добавить к любому запросу обратной навигации.

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

Недопустимые маршруты

Следующие форматы маршрутов считаются недопустимыми.

Формат Описание
//страница или / / /страница В настоящее время глобальные маршруты не могут быть единственной страницей в стеке навигации. Таким образом, абсолютная маршрутизация для глобальных маршрутов не поддерживается.

Использование этих форматов маршрутов приводит к созданию исключения Exception.

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

Попытка перехода на несуществующий маршрут приводит к созданию исключения ArgumentException.

Отладка навигации

Некоторые классы оболочки дополняются DebuggerDisplayAttribute, который определяет отображение класса или поля в отладчике. Это помогает в отладке запросов навигации, отображая актуальные данные для запроса перехода. Например, на следующем снимке экрана показаны свойства CurrentItem и CurrentState объекта Shell.Current:

Снимок экрана отладчика

В этом примере свойство CurrentItem с типом FlyoutItem отображает название и маршрут объекта FlyoutItem. Аналогичным образом CurrentState свойство типа ShellNavigationStateотображает универсальный код ресурса (URI) отображаемого маршрута в приложении Оболочки.

Класс Tab определяет Stack свойство типа IReadOnlyList<Page>, представляющее текущий стек навигации в пределах. Tab Класс также предоставляет следующие переопределимые методы навигации:

  • GetNavigationStack, возвращает IReadOnlyList<Page>текущий стек навигации.
  • OnInsertPageBefore, который вызывается при вызове метода INavigation.InsertPageBefore.
  • OnPopAsync, который возвращает Task<Page> и вызывается при вызове INavigation.PopAsync.
  • OnPopToRootAsync, который возвращает Task и вызывается при вызове INavigation.OnPopToRootAsync.
  • OnPushAsync, который возвращает Task и вызывается при вызове INavigation.PushAsync.
  • OnRemovePage, который вызывается при вызове метода INavigation.RemovePage.

В следующем примере показано переопределение метода OnRemovePage:

public class MyTab : Tab
{
    protected override void OnRemovePage(Page page)
    {
        base.OnRemovePage(page);

        // Custom logic
    }
}

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

Класс Shell определяет событие Navigating, которое возникает перед выполнением любого перехода — программного или вызванного действием пользователя. Объект ShellNavigatingEventArgs, который прилагается к событию Navigating, содержит следующие свойства:

Свойство Type Описание
Current ShellNavigationState URI текущей страницы.
Source ShellNavigationSource Тип выполненного перехода.
Target ShellNavigationState URI, представляющий целевой объект навигации.
CanCancel bool Значение, указывающее, возможна ли отмена перехода.
Cancelled bool Значение, указывающее, была ли навигация отменена.

Кроме того, класс ShellNavigatingEventArgs предоставляет метод Cancel, позволяющий отменить переход, и метод GetDeferral, возвращающий токен ShellNavigatingDeferral, который можно использовать для завершения перехода. Дополнительные сведения: Отложенный переход.

Класс Shell также определяет событие Navigated, которое возникает при завершении навигации. Объект ShellNavigatedEventArgs, который прилагается к событию Navigated, содержит следующие свойства:

Свойство Type Описание
Current ShellNavigationState URI текущей страницы.
Previous ShellNavigationState URI предыдущей страницы.
Source ShellNavigationSource Тип выполненного перехода.

Внимание

Метод OnNavigating вызывается, когда генерируется событие Navigating. Аналогично, метод OnNavigated вызывается, когда генерируется событие Navigated. Оба метода можно переопределить в подклассе Shell для перехвата запросов навигации.

Классы ShellNavigatedEventArgs и ShellNavigatingEventArgs имеют свойства Source с типом ShellNavigationSource. Значения перечисления указаны ниже:

  • Unknown
  • Push
  • Pop
  • PopToRoot
  • Insert
  • Remove
  • ShellItemChanged
  • ShellSectionChanged
  • ShellContentChanged

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

protected override void OnNavigating(ShellNavigatingEventArgs args)
{
    base.OnNavigating(args);

    // Cancel any back navigation.
    if (args.Source == ShellNavigationSource.Pop)
    {
        args.Cancel();
    }
// }

Переход в рамках оболочки можно перехватить, а затем завершить или отменить в зависимости от пользовательского выбора. Для этого можно переопределить метод OnNavigating в подклассе Shell и вызвать метод GetDeferral для объекта ShellNavigatingEventArgs. Этот метод возвращает токен ShellNavigatingDeferral с методом Complete, который можно использовать для завершения запроса о переходе:

public MyShell : Shell
{
    // ...
    protected override async void OnNavigating(ShellNavigatingEventArgs args)
    {
        base.OnNavigating(args);

        ShellNavigatingDeferral token = args.GetDeferral();

        var result = await DisplayActionSheet("Navigate?", "Cancel", "Yes", "No");
        if (result != "Yes")
        {
            args.Cancel();
        }
        token.Complete();
    }    
}

В этом примере отображается лист действий, приглашающий пользователя завершить запрос навигации или отменить его. Переход отменяется вызовом метода Cancel для объекта ShellNavigatingEventArgs. Переход завершается вызовом метода Complete для токена ShellNavigatingDeferral, полученного методом GetDeferral, для объекта ShellNavigatingEventArgs.

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

Если пользователь пытается выполнить переход, когда имеется ожидающий отложенный переход, метод GoToAsync выдает исключение InvalidOperationException.

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

Примитивные данные можно передать в виде строковых параметров запроса при выполнении программной навигации на основе URI. Для этого в конец маршрута добавляется ?, а затем идентификатор параметра запроса, символ =и значение для этого параметра:

async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
    await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}");
}

В этом примере извлекается выбранный в данный момент слон в CollectionViewмаршруте elephantName и передается в elephantdetails качестве параметра запроса.

Передача нескольких данных навигации на основе объектов

Несколько данных навигации на основе объектов могут передаваться с перегрузкой GoToAsync , указывающей IDictionary<string, object> аргумент:

async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
    var navigationParameter = new Dictionary<string, object>
    {
        { "Bear", animal }
    };
    await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}

В этом примере извлекается выбранный в данный момент медведь в CollectionViewкачестве Animalносителя. Объект Animal добавляется в Dictionary ключ Bear. Затем навигация по beardetails маршруту выполняется с Dictionary передачей в качестве параметра навигации.

Все данные, передаваемые в качестве IDictionary<string, object> аргумента, хранятся в памяти в течение всего времени существования страницы и не освобождаются до тех пор, пока страница не будет удалена из стека навигации. Это может быть проблематично, как показано в следующем сценарии:

  1. Page1 переходит к Page2 использованию GoToAsync метода, передавая объект с именем MyData. Page2 затем получает в MyData качестве параметра запроса.
  2. Page2 переходит к Page3 использованию GoToAsync метода без передачи данных.
  3. Page3 перемещается назад с GoToAsync помощью метода. Page2 затем снова получает MyData в качестве параметра запроса.

Хотя это желательно во многих сценариях, если оно не требуется, следует очистить IDictionary<string, object> аргумент с Clear помощью метода после первого получения страницей.

Передача данных навигации на основе объектов с одним использованием

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

async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
    var navigationParameter = new ShellNavigationQueryParameters
    {
        { "Bear", animal }
    };
    await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}

В этом примере извлекается выбранный в данный момент медведь в CollectionViewвиде Animal добавляемого в ShellNavigationQueryParameters объект. Затем выполняется переход к beardetails маршруту с ShellNavigationQueryParameters объектом, передаваемым в качестве параметра навигации. После очистки данных в объекте ShellNavigationQueryParameters навигации.

Получение данных навигации

Существует два подхода к получению данных навигации.

  1. Класс той страницы, на которую осуществляется переход, или класс BindingContext этой страницы можно дополнить атрибутом QueryPropertyAttribute для каждого параметра запроса. Дополнительные сведения об обработке данных навигации с помощью атрибутов свойств запроса см. в этом разделе.
  2. Класс той страницы, на которую осуществляется переход, или класс BindingContext этой страницы может реализовать интерфейс IQueryAttributable. Дополнительные сведения об обработке данных навигации с помощью одного метода см. в этом разделе.

Обработка данных навигации с помощью атрибутов свойств запроса

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

[QueryProperty(nameof(Bear), "Bear")]
public partial class BearDetailPage : ContentPage
{
    Animal bear;
    public Animal Bear
    {
        get => bear;
        set
        {
            bear = value;
            OnPropertyChanged();
        }
    }

    public BearDetailPage()
    {
        InitializeComponent();
        BindingContext = this;
    }
}

В этом примере первый аргумент для QueryPropertyAttribute свойства указывает имя свойства, которое будет получать данные, с вторым аргументом, указывающим идентификатор параметра. Поэтому в приведенном выше примере указывается, QueryPropertyAttribute что Bear свойство получит данные, переданные в параметре навигации в Bear вызове GoToAsync метода.

Примечание.

Значения параметров запроса на основе строк, получаемые с помощью QueryPropertyAttribute автоматически декодированного URL-адреса.

Обработка данных навигации с помощью одного метода

Данные навигации можно получить, реализовав в принимающем классе интерфейс IQueryAttributable. Интерфейс IQueryAttributable указывает, что реализующий класс должен реализовать метод ApplyQueryAttributes. У этого метода есть аргумент query типа IDictionary<string, object>, который содержит любые данные, передаваемые в процессе навигации. Каждый ключ в словаре — это идентификатор параметра запроса с его значением, соответствующим объекту, представляющего данные. Преимущество использования этого подхода заключается в том, что данные навигации можно обрабатывать с помощью одного метода. Это может быть полезно, если у вас есть несколько элементов данных навигации, требующих обработки в целом.

В следующем примере показан класс модели представления, реализующий интерфейс IQueryAttributable:

public class MonkeyDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
    public Animal Monkey { get; private set; }

    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        Monkey = query["Monkey"] as Animal;
        OnPropertyChanged("Monkey");
    }
    ...
}

В этом примере ApplyQueryAttributes метод извлекает объект, Monkey соответствующий ключу query в словаре, который был передан в качестве аргумента вызову GoToAsync метода.

Внимание

Строковые значения параметров запроса, полученные через IQueryAttributable интерфейс, не декодируются автоматически.

Передача и обработка нескольких элементов данных

Несколько параметров запроса на основе строк можно передать, подключив их к &. Например, следующий код передает два элемента данных:

async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
    string elephantLocation = (e.CurrentSelection.FirstOrDefault() as Animal).Location;
    await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}&location={elephantLocation}");
}

Этот пример кода получает значения выбранного слона в параметре CollectionView и переходит по маршруту elephantdetails, передавая elephantName и elephantLocation как параметры запроса.

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

[QueryProperty(nameof(Name), "name")]
[QueryProperty(nameof(Location), "location")]
public partial class ElephantDetailPage : ContentPage
{
    public string Name
    {
        set
        {
            // Custom logic
        }
    }

    public string Location
    {
        set
        {
            // Custom logic
        }
    }
    ...    
}

В этом примере класс имеет атрибут QueryPropertyAttribute для каждого параметра запроса. Первый атрибут QueryPropertyAttribute указывает, что свойство Name получит данные, переданные в параметре запроса name, а второй атрибут QueryPropertyAttribute указывает, что свойство Location получит данные, переданные в параметре запроса location. В обоих случаях значения параметров запросов указываются в URI в вызове метода GoToAsync.

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

public class ElephantDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
    public Animal Elephant { get; private set; }

    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        string name = HttpUtility.UrlDecode(query["name"].ToString());
        string location = HttpUtility.UrlDecode(query["location"].ToString());
        ...        
    }
    ...
}

В этом примере метод ApplyQueryAttributes извлекает значение параметров запроса name и location из URI в вызов метода GoToAsync.

Примечание.

Параметры запроса на основе строк и параметры навигации на основе объектов могут одновременно передаваться при выполнении навигации на основе маршрутов.

Действие кнопки "Назад"

Внешний вид и поведение кнопки "Назад" можно переопределить, присвоив присоединенное свойство BackButtonBehavior объекту BackButtonBehavior. Класс BackButtonBehavior определяет следующие свойства:

  • Command с типом ICommand, который выполняется при нажатии кнопки "Назад".
  • CommandParameter с типом object, который передается как параметр в Command.
  • IconOverride с типом ImageSource, который содержит значок для кнопки "Назад".
  • IsEnabled с типом boolean, который указывает, доступна ли кнопка перехода назад. Значение по умолчанию — true.
  • IsVisiblebooleanТип , указывает, отображается ли кнопка "Назад". Значение по умолчанию — true.
  • TextOverride с типом string, который содержит текст для кнопки "Назад".

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

В следующем коде показан пример переопределения внешнего вида и поведения кнопки "Назад":

<ContentPage ...>    
    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"
                            IconOverride="back.png" />   
    </Shell.BackButtonBehavior>
    ...
</ContentPage>

Свойство Command получает значение ICommand для выполнения при нажатии кнопки "Назад", а в свойстве IconOverride сохраняется значок, используемый для кнопки "Назад":

Снимок экрана: переопределение значка кнопки