結構化巡覽概觀

可由 XAML 瀏覽器應用程式 (XBAP) 裝載的內容、 FrameNavigationWindow 是由頁面所組成,這些頁面可由套件統一資源識別項 (URI) 識別,並透過超連結流覽至 。 頁面的結構及其可被巡覽的方式,如超連結所定義,稱之為巡覽拓撲。 這種拓撲適合各種不同的應用程式類型,尤其是巡覽文件的應用程式。 針對這類應用程式,使用者可以從一頁巡覽到另一頁,頁面彼此間不需要了解。

不過,其他類型的應用程式有需要知道被巡覽的頁面。 例如,假設人力資源應用程式有列出組織中所有員工的頁面:「員工清單」頁面。 此頁面也允許使用者按一下超連結新增新進員工。 按一下時,頁面會巡覽至「新增員工」頁面,收集新進員工的詳細資料,並傳回「員工清單」頁面建立新的員工以及更新清單。 這種巡覽樣式類似於呼叫方法執行一些處理並傳回值,稱之為結構化程式設計。 因此,這種巡覽稱之為「結構化巡覽」

類別 Page 不會實作結構化導覽的支援。 相反地,類別 PageFunction<T> 衍生自 Page ,並使用結構化導覽所需的基本建構加以擴充。 本主題說明如何使用 建立結構化導覽 PageFunction<T>

結構化巡覽

當一個頁面在結構化巡覽中呼叫另一個頁面時,需要下列部分或全部行為︰

  • 呼叫端頁面會巡覽至呼叫的頁面,並選擇性地傳遞被呼叫頁面所需的參數。

  • 當使用者用完呼叫端頁面時,呼叫的頁面會選擇性特別傳回給呼叫端頁面︰

    • 傳回狀態資訊,說明如何完成呼叫端頁面 (例如,使用者按下 [確定] 按鈕或 [取消] 按鈕)。

    • 傳回收集的使用者資料 (例如,新進員工的詳細資料)。

  • 當呼叫端頁面傳回被呼叫的頁面時,巡覽記錄會移除呼叫的頁面,隔離呼叫頁面中的各個執行個體。

下圖說明這些行為:

Screenshot shows the flow between calling page and called page.

您可以使用 做為呼叫的頁面來實作 PageFunction<T> 這些行為。

有 PageFunction 的結構化巡覽

本主題說明如何實作包含單 PageFunction<T> 一 之結構化導覽的基本機制。 在此範例中,呼叫 PagePageFunction<T> 以從使用者取得 String 值並傳回它。

建立呼叫端頁面

呼叫 PageFunction<T> 的頁面可以是 PagePageFunction<T> 。 在此範例中,它是 Page ,如下列程式碼所示。

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

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

End Namespace

建立呼叫頁面函式

由於呼叫頁面可以使用呼叫的頁面來收集和傳回使用者的資料,因此會實作為泛型類別, PageFunction<T> 其 type 引數會指定所呼叫頁面將傳回之值的型別。 下列程式碼顯示呼叫頁面的初始實作,使用 PageFunction<T> 會傳回 String 的 。

<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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>
using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

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

End Namespace

PageFunction<T> 宣告類似于 具有新增型別引數之 的宣告 Page 。 如您從程式碼範例中所見,使用 屬性和程式碼後置,使用標準泛型型別引數語法,在 XAML 標記 x:TypeArguments 中指定類型引數。

您不需要只使用 .NET Framework 類別做為類型引數。 PageFunction<T>可以呼叫 來收集抽象為自訂型別的網域特定資料。 下列程式碼示範如何使用自訂型別作為 的 PageFunction<T> 型別引數。

namespace SDKSample
{
    public class CustomType
    {
Public Class CustomType
    }
}
End Class
<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample" 
    x:Class="SDKSample.CustomTypePageFunction"
    x:TypeArguments="local:CustomType">
</PageFunction>
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class CustomTypePageFunction : PageFunction<CustomType>
    {
Partial Public Class CustomTypePageFunction
    Inherits System.Windows.Navigation.PageFunction(Of CustomType)
    }
}
End Class

的型別引數 PageFunction<T> 會提供呼叫頁面與呼叫頁面之間通訊的基礎,如下幾節討論。

如您所見,以 宣告 PageFunction<T> 所識別的類型在將資料從 PageFunction<T> 傳回至呼叫頁面時扮演著重要角色。

呼叫 PageFunction 並傳遞參數

若要呼叫頁面,呼叫頁面必須具現化呼叫的頁面,並使用 Navigate 方法流覽至該頁面。 這可讓呼叫端頁面將初始資料傳遞至呼叫的頁面,例如由呼叫的頁面所收集之資料的預設值。

下列程式碼顯示具有非無參數建構函式的呼叫頁面,以接受來自呼叫頁面的參數。

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();

Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()
    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}
    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub
    }
}
End Class

End Namespace

下列程式碼顯示處理 Click 事件的 Hyperlink 呼叫頁面,以具現化呼叫的頁面,並傳遞初始字串值。

<Hyperlink Name="pageFunctionHyperlink">Call Page Function</Hyperlink>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
            this.pageFunctionHyperlink.Click += new RoutedEventHandler(pageFunctionHyperlink_Click);
        }
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
        AddHandler Me.pageFunctionHyperlink.Click, New RoutedEventHandler(AddressOf Me.pageFunctionHyperlink_Click)
    End Sub
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
}
End Sub
    }
}
End Class

End Namespace

您不需要將參數傳遞給呼叫的頁面。 您反而可以執行下列作業︰

但是,您很快就會發現,您還是需要使用程式碼來具現化並巡覽至呼叫的頁面,才能收集呼叫的頁面所傳回的資料。 基於這個理由, PageFunction<T> 必須保持運作;否則,下次流覽至 PageFunction<T> 時,WPF 會使用無參數建構函式具現化 PageFunction<T>

但在呼叫的頁面傳回之前,它需要傳回呼叫端頁面可擷取的資料。

將工作的工作結果和工作資料傳回給呼叫端頁面

使用者用完呼叫的頁面時,如本例所示,按 [確定] 或 [取消] 按鈕,必須傳回呼叫的頁面。 因為呼叫端頁面使用了被呼叫頁面來收集使用者資料,所以呼叫端頁面需要兩種類型的資訊︰

  1. 使用者是否取消了呼叫的頁面 (本例中為按下 [確定] 按鈕或 [取消] 按鈕)。 這可讓呼叫端頁面決定是否要處理呼叫端頁面收集的使用者資料。

  2. 使用者提供的資料。

若要傳回信息, PageFunction<T> 請實作 OnReturn 方法。 下列程式碼示範如何呼叫它。

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of 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);
        }
    }
}
    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

在本例中,如果使用者按下 [取消] 按鈕,null 值就會傳回呼叫端頁面。 如果改按下 [確定] 按鈕,則傳回使用者提供的字串值。 OnReturn 是您 protected virtual 呼叫的方法,可將資料傳回呼叫頁面。 您的資料必須封裝在泛型 ReturnEventArgs<T> 類型的實例中,其 type 引數會指定傳回的值 Result 類型。 如此一來,當您宣告 PageFunction<T> 具有特定型別引數的 時,即表示 PageFunction<T> 會傳回型別引數所指定的型別實例。 在此範例中,型別引數,因此傳回值的類型為 String

呼叫 時 OnReturn ,呼叫頁面需要某種方式接收 的 PageFunction<T> 傳回值。 基於這個理由, PageFunction<T> 實作 Return 呼叫頁面來處理的事件。 呼叫 時 OnReturnReturn 會引發 ,因此呼叫頁面可以註冊 Return 以接收通知。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits 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;
            }
        }
    }
}
    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

工作完成時移除工作頁面

當傳回呼叫的頁面,而使用者未取消呼叫的頁面時,呼叫端頁面會處理使用者提供以及呼叫的頁面所傳回的資料。 以此方式擷取的資料通常是獨立的活動。當被呼叫頁面傳回時,呼叫端頁面需要建立並巡覽至新的呼叫端頁面,以擷取更多資料。

不過,除非從日誌移除呼叫的頁面,否則使用者就能夠巡覽回到呼叫端頁面的上一個執行個體。 是否 PageFunction<T> 保留于日誌中,是由 RemoveFromJournal 屬性所決定。 根據預設,呼叫 時 OnReturn 會自動移除頁面函式,因為 RemoveFromJournal 設定為 true 。 若要在呼叫 之後 OnReturn 將頁面函式保留在流覽歷程記錄中,請將 設定 RemoveFromJournalfalse

其他類型的結構化巡覽

本主題說明 支援呼叫/傳回結構化導覽的最基本用法 PageFunction<T> 。 此基礎讓您能夠建立更複雜的結構化巡覽類型。

例如,呼叫端頁面有時候需要多個頁面來收集足夠的使用者資料,或執行工作。 使用多個頁面稱之為「精靈」。

在其他情況下,應用程式可能會令相依於結構化巡覽的複雜巡覽拓撲有效運作。 如需詳細資訊,請參閱巡覽拓撲概觀

另請參閱