次の方法で共有


構造化ナビゲーションの概要

XAML ブラウザー アプリケーション (XBAP)、Frame、または NavigationWindow でホストできるコンテンツは、パックの UNIFORM リソース識別子 (URI) で識別し、ハイパーリンクで移動できるページで構成されます。 ページの構造と、ハイパーリンクで定義されているページの移動方法は、ナビゲーション トポロジと呼ばれます。 このようなトポロジは、さまざまな種類のアプリケーション 、特にドキュメント内を移動するアプリケーションに適しています。 このようなアプリケーションの場合、ユーザーは、いずれかのページが他のページについて何も知る必要なく、1 つのページから別のページに移動できます。

ただし、他の種類のアプリケーションでは、ページ間を移動したことを認識する必要があるページがあります。 たとえば、組織内のすべての従業員を一覧表示する 1 つのページ ([従業員の一覧表示] ページ) がある人事アプリケーションを考えてみましょう。 このページでは、ユーザーがハイパーリンクをクリックして新しい従業員を追加することもできます。 クリックすると、新しい従業員の詳細を収集する [従業員の追加] ページに移動し、[従業員の一覧] ページに戻って新しい従業員を作成し、リストを更新します。 このスタイルのナビゲーションは、メソッドを呼び出して何らかの処理を実行し、値を返すことと似ています。これは構造化プログラミングと呼ばれます。 そのため、このスタイルのナビゲーションは、構造化ナビゲーションと呼ばれます。

Page クラスは、構造化ナビゲーションのサポートを実装していません。 代わりに、PageFunction<T> クラスは Page から派生し、構造化ナビゲーションに必要な基本的なコンストラクトで拡張します。 このトピックでは、PageFunction<T>を使用して構造化ナビゲーションを確立する方法について説明します。

構造化ナビゲーション

あるページが構造化ナビゲーションで別のページを呼び出す場合、次の動作の一部またはすべてが必要です。

  • 呼び出し元のページは呼び出されたページに移動し、必要に応じて呼び出されたページに必要なパラメーターを渡します。

  • 呼び出されたページは、ユーザーが呼び出し元ページの使用を終了した後、必要に応じてそのページに戻ることができます。

    • 呼び出し元ページの完了方法を説明する状態情報を返します (たとえば、ユーザーが [OK] ボタンまたは [キャンセル] ボタンを押したかどうか)。

    • ユーザーから収集されたデータを返す (たとえば、新しい従業員の詳細)。

  • 呼び出し元のページが呼び出し元のページに戻ると、呼び出されたページがナビゲーション履歴から削除され、呼び出されたページのインスタンスが別のページから分離されます。

これらの動作を次の図に示します。

スクリーンショットは、呼び出し元のページと呼び出されたページの間のフローを示しています。

これらの動作は、呼び出されたページとして PageFunction<T> を使用して実装できます。

PageFunction を使用した構造化ナビゲーション

このトピックでは、1 つの PageFunction<T>を含む構造化ナビゲーションの基本的なメカニズムを実装する方法について説明します。 このサンプルでは、PagePageFunction<T> を呼び出して、ユーザーから String 値を取得して返します。

呼び出し元ページの作成

PageFunction<T> を呼び出すページには、Page または PageFunction<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> は、呼び出されたページが返す値の型を指定する型引数を持つジェネリック クラスとして実装されます。 呼び出されたページの初期実装を示す次のコードは、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

次のコードは、呼び出されたページをインスタンス化して初期文字列値を渡す HyperlinkClick イベントを処理する呼び出し元のページを示しています。

<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

呼び出されたページにパラメーターを渡す必要はありません。 代わりに、次の操作を行うことができます。

  • 呼び出し元のページから:

    1. パラメーターなしのコンストラクターを使用して、呼び出された PageFunction<T> をインスタンス化します。

    2. パラメーターを Propertiesに格納します。

    3. 呼び出された PageFunction<T>に移動します。

  • 呼び出された PageFunction<T>から:

    • Propertiesに格納されているパラメーターを取得して使用します。

ただし、すぐにわかるように、呼び出されたページから返されたデータを収集するには、呼び出されたページをインスタンス化して移動するコードを使用する必要があります。 このため、PageFunction<T> を維持する必要があります。それ以外の場合、次に PageFunction<T>に移動すると、WPF はパラメーターなしのコンストラクターを使用して PageFunction<T> をインスタンス化します。

ただし、呼び出されたページが返される前に、呼び出し元のページで取得できるデータを返す必要があります。

タスクから呼び出し元ページにタスクの結果とタスク データを返す

ユーザーが呼び出されたページの使用を完了したら、この例で示されている [OK] または [キャンセル] ボタンを押すと、呼び出されたページが返される必要があります。 呼び出し元ページは呼び出し元のページを使用してユーザーからデータを収集するため、呼び出し元のページには次の 2 種類の情報が必要です。

  1. ユーザーが呼び出されたページをキャンセルしたかどうか (この例では[OK] ボタンまたは [キャンセル] ボタンを押します)。 これにより、呼び出し元ページは、呼び出し元のページがユーザーから収集したデータを処理するかどうかを決定できます。

  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 の値が呼び出し元のページに返されます。 代わりに [OK] ボタンを押すと、ユーザーが指定した文字列値が返されます。 OnReturn は、呼び出し元のページにデータを返すために呼び出す protected virtual メソッドです。 データは、ジェネリック ReturnEventArgs<T> 型のインスタンスにパッケージ化する必要があります。その型引数は、Result 返される値の型を指定します。 このように、特定の型引数を持つ PageFunction<T> を宣言すると、PageFunction<T> は型引数で指定された型のインスタンスを返すように指定します。 この例では、型引数とその結果として、戻り値は String型です。

OnReturn が呼び出されると、呼び出し元ページで PageFunction<T>の戻り値を受け取る何らかの方法が必要になります。 このため、PageFunction<T> は、処理するページを呼び出すための Return イベントを実装します。 OnReturn が呼び出されると、Return が発生するため、呼び出し元のページは通知を受信するために 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 プロパティによって決まります。 既定では、RemoveFromJournaltrueに設定されているため、OnReturn が呼び出されると、ページ関数は自動的に削除されます。 OnReturn が呼び出された後もページ関数をナビゲーション履歴に保持するには、RemoveFromJournalfalseに設定します。

その他の種類の構造化ナビゲーション

このトピックでは、呼び出し/戻り構造化ナビゲーションをサポートする PageFunction<T> の最も基本的な使用方法について説明します。 この基盤では、より複雑な種類の構造化ナビゲーションを作成できます。

たとえば、ユーザーから十分なデータを収集したり、タスクを実行したりするために、呼び出し元のページで複数のページが必要になる場合があります。 複数のページの使用は、"ウィザード" と呼ばれます。

また、アプリケーションには、効果的に動作するための構造化ナビゲーションに依存する複雑なナビゲーション トポロジが存在する場合があります。 詳細については、「ナビゲーション トポロジの概要」を参照してください。

関連項目