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


Общие сведения о структурной навигации

Обновлен: Ноябрь 2007

Содержимое, которое может быть размещено приложением обозревателя XBAP (XAML browser application — приложение обозревателя XAML), объектом Frame или NavigationWindow, состоит из страниц, которые могут определяться URI (uniform resource identifiers — универсальные коды ресурса) пакета и просматриваться с помощью гиперссылок. Структура страниц и способы, с помощью которых их можно просмотреть с помощью гиперссылок, называется топологией навигации. Такая топология подходит для различных типов приложений, особенно тех, которые осуществляют навигацию по документам. Для таких приложений пользователю необязательно знать что-либо о других страницах при перемещении с одной страницы на другую.

Однако другие типы приложений содержат страницы, которые должны быть известны при перемещении между ними. Например, рассмотрим приложение управления персоналом, имеющее одну страницу со списком всех сотрудников организации — страница «Список сотрудников». Эта страница могла бы также разрешить пользователям добавлять нового сотрудника, щелкнув гиперссылку. После щелчка выполняется переход на страницу «Добавить сотрудника», чтобы собрать сведения о новом сотруднике, и возврат к странице «Список сотрудников», чтобы добавить нового сотрудника и обновить список. Этот стиль перехода аналогичен вызову метода для выполнения обработки и возврата значения, что называется структурным программированием. Такой стиль перехода называется структурная навигация.

Класс Page не реализует поддержку структурной навигации. Вместо этого, класс PageFunction<T> производится из класса Page и расширяет его с помощью основных конструкций, необходимых для структурированных переходов. В этом разделе показано, как установить структурную навигацию, используя объект PageFunction<T>.

ms741843.alert_note(ru-ru,VS.90).gifПримечание.

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

В этом разделе содержатся следующие подразделы.

  • Структурная навигация
  • Структурная навигация с помощью PageFunction
  • Другие типы структурной навигации
  • Связанные разделы

Структурная навигация

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

  • Вызывающая страница которая переходит к вызванной странице, при необходимости, передает ей необходимые параметры.

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

    • Возвращение сведений о состоянии, описывающие, как была завершена вызывающая страница (например, какую кнопку нажал пользователь: «ОК» или «Отмена»).

    • Возвращение данных, которые были собраны от пользователя (например, сведения о новом сотруднике).

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

Это поведение показано на следующем рисунке.

Поток между вызывающей страницей и вызываемой страницей

Для реализации этого поведения можно использовать объект PageFunction<T> в качестве вызванной страницы.

Структурная навигация с помощью PageFunction

В этом разделе показано, как реализовать основной механизм структурной навигации с помощью одного объекта PageFunction<T>. В этом примере объект Page вызывает объект PageFunction<T>, чтобы получить значение String от пользователя и вернуть его.

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

Страница, которая вызывает PageFunction<T>, может быть Page или PageFunction<T>. В данном примере, это Page, как показано в следующем коде.

<Page 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">


...


</Page>
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler, Visibility
Imports System.Windows.Controls ' Page
Imports System.Windows.Navigation ' ReturnEventArgs

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()


...


End Sub


...


End Class

End Namespace
using System.Windows; // RoutedEventArgs, RoutedEventHandler, Visibility
using System.Windows.Controls; // Page
using System.Windows.Navigation; // ReturnEventArgs

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();


...


}


...


    }
}

Создание функции страницы для вызова

Поскольку вызывающая страница может использовать вызванную страницу для сбора и возврата данных от пользователя, объект PageFunction<T> реализован как базовый класс, тип аргумента которого определяет тип значения, которое вернет вызванная страница. Следующий код показывает начальную реализацию вызванной страницы, используя объект PageFunction<T>, который возвращает String.

<PageFunction
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    x:Class="StructuredNavigationSample.CalledPageFunction"
    x:TypeArguments="sys:String"
    Title="Page Function" 
    WindowWidth="250" WindowHeight="150">

  <Grid Margin="10">

    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>

    <!-- Data -->
    <Label Grid.Column="0" Grid.Row="0">DataItem1:</Label>
    <TextBox Grid.Column="1" Grid.Row="0" Name="dataItem1TextBox"></TextBox>

    <!-- Accept/Cancel buttons -->
    <TextBlock Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right">
      <Button Name="okButton" IsDefault="True" MinWidth="50">OK</Button>
      <Button Name="cancelButton" IsCancel="True" MinWidth="50">Cancel</Button>
    </TextBlock>

  </Grid>

</PageFunction>
Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
    Public Sub New()
        Me.InitializeComponent()
    End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }


...


    }
}

Объявление объекта PageFunction<T> похоже на объявление объекта Page с добавлением аргументов типа. Как видно из примера кода, аргументы типа указаны в обеих метках XAML, с помощью атрибута x:TypeArguments, и фоновом коде, с помощью стандартного синтаксиса аргумента универсального типа.

Нет необходимости использовать только классы .NET Framework в качестве аргументов типа. Объект PageFunction<T> может быть вызван для сбора данных отдельного домена, которые абстрагированы как пользовательский типа. В следующем коде показано использование пользовательского типа в качестве аргумента типа для объекта PageFunction<T>.

Аргументы типа для объекта PageFunction<T> обеспечивают основу для связи между вызывающей и вызываемой страницами, которая рассматривается в следующих разделах.

Как можно видеть дальше, тип, который определен с помощью объявления объекта PageFunction<T>, играет важную роль в возвращении данных из объекта PageFunction<T> в вызывающую страницу.

Вызов PageFunction и передача параметров

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

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

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()


...


    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();



...


    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}

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

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()


...


    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();



...


    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}

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

  • Их вызывающей страницы:

    1. Создайте экземпляр вызываемого объекта PageFunction<T> с помощью конструктора по умолчанию.

    2. Сохраните параметры в свойстве Properties.

    3. Перейдите к вызываемому объекту PageFunction<T>.

  • Из вызываемого объекта PageFunction<T>:

    • Извлеките и используйте параметры, хранящиеся в свойстве Properties.

Но, как будет сразу видно, по-прежнему нужно использовать код для создания экземпляра и перехода к вызываемой странице для сбора возвращаемых ею данных. По этой причине, объект PageFunction<T> должен поддерживаться активным; в противном случае, при следующем переходе к объекту PageFunction<T>WPF создает экземпляр PageFunction<T> с помощью конструктора по умолчанию.

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

Возвращение результатов и данных задачи из задачи в вызывающую страницу

Когда пользователь завершил работу с вызванной страницей — в этом примере нажатием кнопки «ОК» или «Отмена» — вызванная страница должна вернуться. Поскольку вызывающая страница использует вызванную страницу для сбора данных от пользователя, вызывающая страница требует два типа данных:

  1. Отменил ли пользователь вызванную страницу (в этом примере — с помощью нажатия кнопки «ОК» или «Отмена»). Это позволяет вызывающей странице определить, требуется ли обработка данных, собранных вызванной страницей от пользователя.

  2. Данные, которые были предоставлены пользователем.

Для возврата данных объект PageFunction<T> реализует метод OnReturn. Следующий код иллюстрирует, как его вызвать.

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


    Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Accept when Ok button is clicked
        Me.OnReturn(New ReturnEventArgs(Of String)(Me.dataItem1TextBox.Text))
    End Sub

    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Cancel
        Me.OnReturn(Nothing)
    End Sub
End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


        void okButton_Click(object sender, RoutedEventArgs e)
        {
            // Accept when Ok button is clicked
            OnReturn(new ReturnEventArgs<string>(this.dataItem1TextBox.Text));
        }

        void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            // Cancel 
            OnReturn(null);
        }
    }
}

В этом примере, если пользователь нажимает кнопку «Отмена», вызывающей странице возвращается значение null. Если нажата кнопка «ОК», возвращается значение строки, предоставленное пользователем. Метод OnReturn является методом protected virtual, который вызывается для возвращения данных вызывающей странице. Данные необходимо упаковать в экземпляре универсального типа ReturnEventArgs<T>, тип аргумента которого указывает тип значения, возвращающего свойство Result. Таким образом, при объявлении объекта PageFunction<T> с определенным аргументом типа, пользователь заявляет, что объект PageFunction<T> вернет экземпляр типа, который определен аргументом типа. В этом примере, аргумент типа и, следовательно, возвращенное значение является объектом String типа.

При вызове метода OnReturn вызывающей странице требуется способ получения возвращенного значения PageFunction<T>. По этой причине, PageFunction<T> реализует событие Return для вызывающей страницы для обработки. При вызове метода OnReturn вызывается событие Return, поэтому вызывающая страница может зарегистрировать событие Return для получения уведомления.

Imports System.Windows ' RoutedEventArgs, RoutedEventHandler, Visibility
Imports System.Windows.Controls ' Page
Imports System.Windows.Navigation ' ReturnEventArgs

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page


...


    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate and navigate to page function
        Dim calledPageFunction As New CalledPageFunction("Initial Data Item Value")
        AddHandler calledPageFunction.Return, New ReturnEventHandler(Of String)(AddressOf Me.calledPageFunction_Return)
        MyBase.NavigationService.Navigate(calledPageFunction)
    End Sub
    Private Sub calledPageFunction_Return(ByVal sender As Object, ByVal e As ReturnEventArgs(Of String))

        Me.pageFunctionResultsTextBlock.Visibility = Windows.Visibility.Visible

        ' Display result
        Me.pageFunctionResultsTextBlock.Text = IIf((Not e Is Nothing), "Accepted", "Canceled")

        ' If page function returned, display result and data
        If (Not e Is Nothing) Then
            Me.pageFunctionResultsTextBlock.Text = (Me.pageFunctionResultsTextBlock.Text & ChrW(10) & e.Result)
        End If

    End Sub
End Class

End Namespace
using System.Windows; // RoutedEventArgs, RoutedEventHandler, Visibility
using System.Windows.Controls; // Page
using System.Windows.Navigation; // ReturnEventArgs

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {


...


        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
            CalledPageFunction.Return += pageFunction_Return;
            this.NavigationService.Navigate(CalledPageFunction);
        }
        void pageFunction_Return(object sender, ReturnEventArgs<string> e)
        {
            this.pageFunctionResultsTextBlock.Visibility = Visibility.Visible;

            // Display result
            this.pageFunctionResultsTextBlock.Text = (e != null ? "Accepted" : "Canceled");

            // If page function returned, display result and data
            if (e != null)
            {
                this.pageFunctionResultsTextBlock.Text += "\n" + e.Result;
            }
        }
    }
}

Удаление страниц задачи при ее завершении

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

Однако если вызванная страница не удалена из журнала, пользователь может вернуться к предыдущему экземпляру вызывающей страницы. Сохранен ли объект PageFunction<T> в журнале, определяется свойством RemoveFromJournal. По умолчанию функция страницы автоматически удаляется при вызове метода OnReturn, так как для свойства RemoveFromJournal установлено значение true. Чтобы сохранить функцию страницы в истории переходов после вызова метода OnReturn, задайте для свойства RemoveFromJournal значение false.

Другие типы структурной навигации

В этом разделе показано большинство основных способов использования объекта PageFunction<T> для поддержки вызова/возврата структурной навигации. Эта база обеспечивает возможность создания более сложных типов структурных переходов.

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

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

См. также

Задачи

Пример структурированного перехода

Основные понятия

Общие сведения о топологии переходов

Ссылки

PageFunction<T>

NavigationService