Модальные страницы Xamarin.FormsXamarin.Forms Modal Pages

Скачать пример Скачать примерDownload Sample Download the sample

Xamarin.Forms поддерживает модальные страницы. На модальной странице пользователь должен выполнить отдельную задачу, причем он не может уйти с этой страницы, пока задача не будет выполнена или отменена. В этой статье демонстрируется переход на модальные страницы.Xamarin.Forms provides support for modal pages. A modal page encourages users to complete a self-contained task that cannot be navigated away from until the task is completed or cancelled. This article demonstrates how to navigate to modal pages.

Темы этой статьи:This article discusses the following topics:

  • Выполнение навигации — помещение страниц в модальный стек, извлечение страниц из модального стека, отключение кнопки "Назад" и анимация перехода между страницами.Performing navigation – pushing pages to the modal stack, popping pages from the modal stack, disabling the back button, and animating page transitions.
  • Передача данных при навигации — передача данных через конструктор страницы и через BindingContext.Passing data when navigating – passing data through a page constructor, and through a BindingContext.

ОбзорOverview

Модальная страница может быть любого из типов Page, поддерживаемых Xamarin.Forms.A modal page can be any of the Page types supported by Xamarin.Forms. Для отображения модальной страницы приложение помещает ее в модальный стек, где она становится активной страницей, как показано на следующей схеме.To display a modal page the application will push it onto the modal stack, where it will become the active page, as shown in the following diagram:

Для возврата к предыдущей странице приложение извлекает текущую страницу из модального стека, после чего активной становится верхняя страница в стеке, как показано на следующей схеме.To return to the previous page the application will pop the current page from the modal stack, and the new topmost page becomes the active page, as shown in the following diagram:

Выполнение навигацииPerforming Navigation

Методы модальной навигации предоставляются свойством Navigation любых типов, производных от класса Page.Modal navigation methods are exposed by the Navigation property on any Page derived types. Эти методы дают возможность помещать модальные страницы в модальный стек и извлекать модальные страницы из него.These methods provide the ability to push modal pages onto the modal stack, and pop modal pages from the modal stack.

Свойство Navigation также предоставляет свойство ModalStack, из которого можно получить модальные страницы в модальном стеке.The Navigation property also exposes a ModalStack property from which the modal pages in the modal stack can be obtained. Однако не существует средств для работы с модальным стеком или перехода к корневой странице модальной навигации.However, there is no concept of performing modal stack manipulation, or popping to the root page in modal navigation. Причина в том, что такие операции поддерживаются не всеми базовыми платформами.This is because these operations are not universally supported on the underlying platforms.

Примечание

Экземпляр NavigationPage не требуется для навигации по модальным страницам.A NavigationPage instance is not required for performing modal page navigation.

Помещение страниц в модальный стекPushing Pages to the Modal Stack

Для перехода к странице ModalPage необходимо вызвать метод PushModalAsync свойства Navigation текущей страницы, как показано в следующем примере кода.To navigate to the ModalPage it is necessary to invoke the PushModalAsync method on the Navigation property of the current page, as demonstrated in the following code example:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    ...
    await Navigation.PushModalAsync (detailPage);
  }
}

В результате в модальный стек помещается экземпляр ModalPage, где он становится активной страницей, при условии что элемент был выбран в представлении ListView в экземпляре MainPage.This causes the ModalPage instance to be pushed onto the modal stack, where it becomes the active page, provided that an item has been selected in the ListView on the MainPage instance. Экземпляр ModalPage показан на следующих снимках экрана.The ModalPage instance is shown in the following screenshots:

При вызове PushModalAsync происходят указанные ниже события:When PushModalAsync is invoked, the following events occur:

  • Вызывается переопределение OnDisappearing страницы, вызывающей PushModalAsync, при условии что базовой платформой не является Android.The page calling PushModalAsync has its OnDisappearing override invoked, provided that the underlying platform isn't Android.
  • Вызывается переопределение OnAppearing страницы, к которой осуществляется переход.The page being navigated to has its OnAppearing override invoked.
  • Задача PushAsync завершается.The PushAsync task completes.

Однако точный порядок, в котором происходят эти события, зависит от платформы.However, the precise order that these events occur is platform dependent. Дополнительные сведения см. в главе 24 книги Xamarin.Forms Чарльза Петцольда (Charles Petzold).For more information, see Chapter 24 of Charles Petzold's Xamarin.Forms book.

Примечание

Вызовы переопределений OnDisappearing и OnAppearing не могут рассматриваться как гарантия перехода на страницу.Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. Например, в iOS переопределение OnDisappearing вызывается на активной странице, когда приложение завершает работу.For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.

Извлечение страниц из модального стекаPopping Pages from the Modal Stack

Активная страница может быть извлечена из модального стека путем нажатия кнопки Назад на устройстве, причем это может быть как физическая кнопка, так и кнопка на экране.The active page can be popped from the modal stack by pressing the Back button on the device, regardless of whether this is a physical button on the device or an on-screen button.

Чтобы вернуться на исходную страницу программным образом, экземпляр ModalPage должен вызвать метод PopModalAsync, как показано в следующем примере кода:To programmatically return to the original page, the ModalPage instance must invoke the PopModalAsync method, as demonstrated in the following code example:

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  await Navigation.PopModalAsync ();
}

В результате экземпляр ModalPage удаляется из модального стека, а активной становится верхняя страница в нем.This causes the ModalPage instance to be removed from the modal stack, with the new topmost page becoming the active page. При вызове PopModalAsync происходят указанные ниже события.When PopModalAsync is invoked, the following events occur:

  • У страницы, вызывающей PopModalAsync, вызывается переопределение OnDisappearing.The page calling PopModalAsync has its OnDisappearing override invoked.
  • Вызывается переопределение OnAppearing страницы, на которую выполняется возврат, при условии что базовой платформой не является Android.The page being returned to has its OnAppearing override invoked, provided that the underlying platform isn't Android.
  • Возвращается задача PopModalAsync.The PopModalAsync task returns.

Однако точный порядок, в котором происходят эти события, зависит от платформы.However, the precise order that these events occur is platform dependent. Дополнительные сведения см. в главе 24 книги Xamarin.Forms Чарльза Петцольда (Charles Petzold).For more information, see Chapter 24 of Charles Petzold's Xamarin.Forms book.

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

В Android пользователь всегда может вернуться на предыдущую страницу, нажав стандартную кнопку Назад на устройстве.On Android, the user can always return to the previous page by pressing the standard Back button on the device. Если пользователь должен выполнить автономную задачу, прежде чем покинуть модальную страницу, кнопка Назад в приложении должна быть отключена.If the modal page requires the user to complete a self-contained task before leaving the page, the application must disable the Back button. Для этого можно переопределить метод Page.OnBackButtonPressed модальной страницы.This can be accomplished by overriding the Page.OnBackButtonPressed method on the modal page. Дополнительные сведения см. в главе 24 книги Xamarin.Forms Чарльза Петцольда (Charles Petzold).For more information see Chapter 24 of Charles Petzold's Xamarin.Forms book.

Анимация переходов по страницамAnimating Page Transitions

Свойство Navigation каждой страницы также предоставляет переопределенные методы отправки и извлечения, которые включают параметр boolean, указывающий, нужно ли отображать анимацию страниц во время перехода, как показано в следующем примере кода.The Navigation property of each page also provides overridden push and pop methods that include a boolean parameter that controls whether to display a page animation during navigation, as shown in the following code example:

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PushModalAsync (new DetailPage (), false);
}

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  // Page appearance not animated
  await Navigation.PopModalAsync (false);
}

Установка для параметра boolean значения false отключает анимацию перехода страницы, а установка для параметра значения true включает анимацию, при условии что она поддерживается используемой платформой.Setting the boolean parameter to false disables the page-transition animation, while setting the parameter to true enables the page-transition animation, provided that it is supported by the underlying platform. Однако методы отправки и извлечения без этого параметра включают анимацию по умолчанию.However, the push and pop methods that lack this parameter enable the animation by default.

Передача данных при переходеPassing Data when Navigating

Иногда странице необходимо передать данные другой странице во время навигации.Sometimes it's necessary for a page to pass data to another page during navigation. Существуют два способа: передача данных с помощью конструктора страниц и указание данных для объекта BindingContext новой страницы.Two techniques for accomplishing this are by passing data through a page constructor, and by setting the new page's BindingContext to the data. Мы обсудим оба способа.Each will now be discussed in turn.

Передача данных через конструктор страницPassing Data through a Page Constructor

Самый простой способ передачи данных на другую страницу во время навигации — в качестве параметра конструктора страниц, как показано в следующем примере кода:The simplest technique for passing data to another page during navigation is through a page constructor parameter, which is shown in the following code example:

public App ()
{
  MainPage = new MainPage (DateTime.Now.ToString ("u")));
}

В этом коде создается экземпляр MainPage для передачи текущих даты и времени в формате ISO8601.This code creates a MainPage instance, passing in the current date and time in ISO8601 format.

Экземпляр MainPage получает данные с помощью параметра конструктора, как показано в следующем примере кода:The MainPage instance receives the data through a constructor parameter, as shown in the following code example:

public MainPage (string date)
{
  InitializeComponent ();
  dateLabel.Text = date;
}

Данные отображаются на странице путем установки свойства Label.Text.The data is then displayed on the page by setting the Label.Text property.

Передача данных через объект BindingContextPassing Data through a BindingContext

Альтернативный способ передачи данных на другую страницу во время навигации —указание данных для объекта BindingContext новой страницы, как показано в следующем примере кода:An alternative approach for passing data to another page during navigation is by setting the new page's BindingContext to the data, as shown in the following code example:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    detailPage.BindingContext = e.SelectedItem as Contact;
    listView.SelectedItem = null;
    await Navigation.PushModalAsync (detailPage);
  }
}

Этот код задает объекту BindingContext экземпляра DetailPage экземпляр Contact, а затем переходит к DetailPage.This code sets the BindingContext of the DetailPage instance to the Contact instance, and then navigates to the DetailPage.

Затем DetailPage использует привязку данных для отображения данных экземпляра Contact, как показано в следующем примере кода XAML.The DetailPage then uses data binding to display the Contact instance data, as shown in the following XAML code example:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ModalNavigation.DetailPage">
    <ContentPage.Padding>
      <OnPlatform x:TypeArguments="Thickness">
        <On Platform="iOS" Value="0,40,0,0" />
      </OnPlatform>
    </ContentPage.Padding>
    <ContentPage.Content>
        <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
            <StackLayout Orientation="Horizontal">
                <Label Text="Name:" FontSize="Medium" HorizontalOptions="FillAndExpand" />
                <Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" />
            </StackLayout>
              ...
            <Button x:Name="dismissButton" Text="Dismiss" Clicked="OnDismissButtonClicked" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

В следующем примере кода показано, как можно выполнить привязку данных в C#:The following code example shows how the data binding can be accomplished in C#:

public class DetailPageCS : ContentPage
{
  public DetailPageCS ()
  {
    var nameLabel = new Label {
      FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
      FontAttributes = FontAttributes.Bold
    };
    nameLabel.SetBinding (Label.TextProperty, "Name");
    ...
    var dismissButton = new Button { Text = "Dismiss" };
    dismissButton.Clicked += OnDismissButtonClicked;

    Thickness padding;
    switch (Device.RuntimePlatform)
    {
        case Device.iOS:
            padding = new Thickness(0, 40, 0, 0);
            break;
        default:
            padding = new Thickness();
            break;
    }

    Padding = padding;
    Content = new StackLayout {
      HorizontalOptions = LayoutOptions.Center,
      VerticalOptions = LayoutOptions.Center,
      Children = {
        new StackLayout {
          Orientation = StackOrientation.Horizontal,
          Children = {
            new Label{ Text = "Name:", FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)), HorizontalOptions = LayoutOptions.FillAndExpand },
            nameLabel
          }
        },
        ...
        dismissButton
      }
    };
  }

  async void OnDismissButtonClicked (object sender, EventArgs args)
  {
    await Navigation.PopModalAsync ();
  }
}

Данные отображаются на странице с помощью нескольких элементов управления Label.The data is then displayed on the page by a series of Label controls.

Дополнительные сведения о привязке данных см. в статье Основы привязки данных.For more information about data binding, see Data Binding Basics.

СводкаSummary

В этой статье был продемонстрирован переход на модальные страницы.This article demonstrated how to navigate to modal pages. На модальной странице пользователь должен выполнить отдельную задачу, причем он не может уйти с этой страницы, пока задача не будет выполнена или отменена.A modal page encourages users to complete a self-contained task that cannot be navigated away from until the task is completed or cancelled.