次の方法で共有


ナビゲーションの概要

Windows Presentation Foundation (WPF) では、スタンドアロン アプリケーションと XAML ブラウザー アプリケーション (XBAP) の 2 種類のアプリケーションで使用できるブラウザー スタイルのナビゲーションがサポートされています。 ナビゲーション用にコンテンツをパッケージ化するために、WPF は Page クラスを提供します。 Pageから別のPageに移動するには、NavigationServiceを使用して宣言的に、またはを使用してプログラムで実行できます。 WPF では、ジャーナルを使用して、移動元のページを記憶し、そのページに戻ります。

PageHyperlinkNavigationService、およびジャーナルは、WPF によって提供されるナビゲーション サポートの中核を形成します。 この概要では、これらの機能について詳しく説明してから、緩やかな拡張アプリケーション マークアップ言語 (XAML) ファイル、HTML ファイル、およびオブジェクトへのナビゲーションを含む高度なナビゲーション サポートについて説明します。

このトピックでは、"browser" という用語は、現在 Microsoft Internet Explorer と Firefox を含む WPF アプリケーションをホストできるブラウザーのみを指します。 特定の WPF 機能が特定のブラウザーでのみサポートされている場合、ブラウザーのバージョンが参照されます。

このトピックでは、WPF の主要なナビゲーション機能の概要について説明します。 これらの機能はスタンドアロン アプリケーションと XBAP の両方で使用できますが、このトピックでは XBAP のコンテキスト内でそれらを示します。

このトピックでは、XBAP をビルドしてデプロイする方法については説明しません。 XBAP の詳細については、「 WPF XAML ブラウザー アプリケーションの概要」を参照してください。

このセクションでは、ナビゲーションの次の側面について説明し、説明します。

ページの実装

WPF では、.NET Framework オブジェクト、カスタム オブジェクト、列挙値、ユーザー コントロール、XAML ファイル、HTML ファイルを含む複数のコンテンツ タイプに移動できます。 ただし、コンテンツをパッケージ化する最も一般的で便利な方法は、 Pageを使用することです。 さらに、 Page はナビゲーション固有の機能を実装して外観を強化し、開発を簡略化します。

Pageを使用すると、次のようなマークアップを使用して、XAML コンテンツのナビゲート可能なページを宣言によって実装できます。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />

XAML マークアップで実装される Page はルート要素として Page されており、WPF XML 名前空間宣言が必要です。 Page要素には、移動して表示するコンテンツが含まれます。 次のマークアップに示すように、 Page.Content プロパティ要素を設定してコンテンツを追加します。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Page.Content>
    <!-- Page Content -->
    Hello, Page!
  </Page.Content>
</Page>

Page.Content 子要素は 1 つだけ含めることができます。前の例では、コンテンツは単一の文字列 "Hello, Page!" です。実際には、通常、レイアウト コントロールを子要素として使用し ( レイアウトを参照)、コンテンツを含め、作成します。

Page要素の子要素はPageの内容と見なされるため、明示的なPage.Content宣言を使用する必要はありません。 次のマークアップは、上記のサンプルと同等の宣言型です。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <!-- Page Content -->
  Hello, Page!
</Page>

この場合、 Page.ContentPage 要素の子要素で自動的に設定されます。 詳細については、「WPF コンテンツ モデルの」を参照してください。

マークアップのみの Page は、コンテンツを表示する場合に便利です。 ただし、 Page では、ユーザーがページを操作できるコントロールを表示することもできます。また、イベントを処理してアプリケーション ロジックを呼び出すことで、ユーザーの操作に応答することもできます。 対話型 Page は、次の例に示すように、マークアップと分離コードの組み合わせを使用して実装されます。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.HomePage">
  Hello, from the XBAP HomePage!
</Page>
using System.Windows.Controls;

namespace SDKSample
{
    public partial class HomePage : Page
    {
        public HomePage()
        {
            InitializeComponent();
        }
    }
}

Imports System.Windows.Controls

Namespace SDKSample
    Partial Public Class HomePage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace

マークアップ ファイルと分離コード ファイルを連携させるには、次の構成が必要です。

  • マークアップでは、 Page 要素に x:Class 属性を含める必要があります。 アプリケーションがビルドされると、マークアップ ファイルにx:Classが存在すると、Microsoft ビルド エンジン (MSBuild) は、partialから派生し、Page属性で指定された名前を持つx:Class クラスを作成します。 これには、XAML スキーマ ( xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ) の XML 名前空間宣言を追加する必要があります。 生成された partial クラスは、イベントを登録し、マークアップで実装されるプロパティを設定するために呼び出される InitializeComponentを実装します。

  • 分離コードでは、クラスは、マークアップのpartial属性で指定されたのと同じ名前のx:Class クラスである必要があり、Pageから派生する必要があります。 これにより、分離コード ファイルを、アプリケーションのビルド時にマークアップ ファイル用に生成される partial クラスに関連付けられます (「 WPF アプリケーションのビルド」を参照)。

  • 分離コードでは、 Page クラスは、 InitializeComponent メソッドを呼び出すコンストラクターを実装する必要があります。 InitializeComponent は、マークアップ ファイルの生成された partial クラスによって実装され、イベントを登録し、マークアップで定義されているプロパティを設定します。

Visual Studio を使用してプロジェクトに新しい Page を追加すると、マークアップと分離コードの両方を使用して Page が実装され、ここで説明するようにマークアップファイルと分離コード ファイルの関連付けを作成するために必要な構成が含まれます。

Pageを作成したら、それに移動できます。 アプリケーションが移動する最初の Page を指定するには、開始 Pageを構成する必要があります。

スタート ページの構成

XBAP では、ブラウザーで一定量のアプリケーション インフラストラクチャをホストする必要があります。 WPF では、 Application クラスは、必要なアプリケーション インフラストラクチャを確立するアプリケーション定義の一部です (「 アプリケーション管理の概要」を参照)。

アプリケーション定義は通常、マークアップと分離コードの両方を使用して実装され、マークアップ ファイルは MSBuildApplicationDefinition 項目として構成されます。 XBAP のアプリケーション定義を次に示します。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App" />
using System.Windows;

namespace SDKSample
{
    public partial class App : Application { }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace

XBAP は、そのアプリケーション定義を使用して開始 Pageを指定できます。これは、XBAP の起動時に自動的に読み込まれる Page です。 そのためには、目的のStartupUriの URI (uniform resource identifier) を使用して Page プロパティを設定します。

ほとんどの場合、 Page はアプリケーションにコンパイルされるか、アプリケーションと共にデプロイされます。 このような場合、 Page を識別する URI はパック URI であり、 パック スキームに 準拠する URI です。 パック URI については、 WPF のパック URI で詳しく説明します。 以下で説明する http スキームを使用してコンテンツに移動することもできます。

次の例に示すように、マークアップ内でStartupUriを宣言的に設定できます。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="PageWithHyperlink.xaml" />

この例では、 StartupUri 属性は、HomePage.xaml を識別する相対パック URI で設定されます。 XBAP が起動すると、HomePage.xaml が自動的に移動して表示されます。 これは、Web サーバーから起動された XBAP を示す次の図で示しています。

XBAP ページ

XBAP の開発と展開の詳細については、「 WPF XAML ブラウザー アプリケーションの概要 」および「 WPF アプリケーションの配置」を参照してください。

ホスト ウィンドウのタイトル、幅、高さの構成

前の図で気づいたことの 1 つは、ブラウザーとタブ パネルの両方のタイトルが XBAP の URI であるということです。 長いだけでなく、タイトルは魅力的でも有益でもありません。 このため、 Page は、 WindowTitle プロパティを設定してタイトルを変更する方法を提供します。 さらに、 WindowWidthWindowHeightをそれぞれ設定することで、ブラウザー ウィンドウの幅と高さを構成できます。

WindowTitleWindowWidth、および WindowHeight は、次の例に示すように、マークアップで宣言によって設定できます。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.HomePage"
    WindowTitle="Page Title"
    WindowWidth="500"
    WindowHeight="200">
  Hello, from the XBAP HomePage!
</Page>

結果を次の図に示します。

ウィンドウ のタイトル、高さ、幅

一般的な XBAP は、複数のページで構成されます。 ページ間を移動する最も簡単な方法は、 Hyperlinkを使用することです。 次のマークアップに示されているHyperlink要素を使用して、PageHyperlinkを宣言によって追加できます。

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page With Hyperlink"
  WindowWidth="250"
  WindowHeight="250">
<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
  Navigate to Another Page
</Hyperlink>
</Page>

Hyperlink要素には、次のものが必要です。

  • 移動するPageのパック URI は、NavigateUri 属性で指定されています。

  • テキストや画像など、ユーザーがクリックしてナビゲーションを開始できるコンテンツ ( Hyperlink 要素に含めることができるコンテンツについては、 Hyperlinkを参照してください)。

次の図は、Pageを備えたHyperlinkの XBAP を示しています。

ハイパーリンク付きページ: ハイパーリンク

予想どおり、Hyperlinkをクリックすると、XBAP は Page 属性によって識別されるNavigateUriに移動します。 さらに、XBAP は Internet Explorer の [最近使ったページ] リストに、前の Page のエントリを追加します。 これを次の図に示します。

[戻る] ボタンと [進む] ボタンは、[

ナビゲーションはPage間の移動をサポートするだけでなく、Hyperlinkもフラグメントナビゲーションをサポートします。

フラグメントのナビゲーション

フラグメント ナビゲーション は、現在の Page または別の Page内のコンテンツ フラグメントへのナビゲーションです。 WPF では、コンテンツ フラグメントは名前付き要素に含まれるコンテンツです。 名前付き要素は、 Name 属性が設定された要素です。 次のマークアップは、コンテンツ フラグメントを含む名前付き TextBlock 要素を示しています。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowTitle="Page With Fragments" >
<!-- Content Fragment called "Fragment1" -->
<TextBlock Name="Fragment1">
  Ea vel dignissim te aliquam facilisis ...
</TextBlock>
</Page>

Hyperlinkがコンテンツ フラグメントに移動するには、NavigateUri属性に次のものが含まれている必要があります。

  • 移動するコンテンツ フラグメントを含む Page の URI。

  • "#" 文字。

  • コンテンツ フラグメントを含む Page 上の要素の名前。

フラグメント URI の形式は次のとおりです。

PageURI#ElementName

コンテンツ フラグメントに移動するように構成された Hyperlink の例を次に示します。

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page That Navigates To Fragment" >
<Hyperlink NavigateUri="PageWithFragments.xaml#Fragment1">
  Navigate To pack Fragment
</Hyperlink>
</Page>

このセクションでは、WPF での既定のフラグメント ナビゲーション実装について説明します。 WPF では、独自のフラグメント ナビゲーション スキームを実装することもできます。一部では、 NavigationService.FragmentNavigation イベントを処理する必要があります。

重要

ルーズ XAML ページ内のフラグメント (ルート要素として Page を持つマークアップのみの XAML ファイル) に移動できるのは、ページを HTTP 経由で参照できる場合のみです。

ただし、緩やかな XAML ページは、独自のフラグメントに移動できます。

Hyperlinkを使用すると、ユーザーは特定のPageへのナビゲーションを開始できます。ページの検索とダウンロードの作業は、NavigationService クラスによって実行されます。 基本的に、 NavigationService は、 Hyperlinkなどのクライアント コードに代わってナビゲーション要求を処理する機能を提供します。 さらに、 NavigationService では、ナビゲーション要求を追跡して影響を与える高度なサポートが実装されています。

Hyperlinkがクリックされると、WPF はNavigationService.Navigateを呼び出して、指定されたパック URI でPageを見つけてダウンロードします。 ダウンロードした Page は、ダウンロードした Pageのインスタンスであるルート オブジェクトを持つオブジェクトのツリーに変換されます。 ルート Page オブジェクトへの参照は、 NavigationService.Content プロパティに格納されます。 移動先のコンテンツのパック URI は NavigationService.Source プロパティに格納され、 NavigationService.CurrentSource は移動先の最後のページのパック URI を格納します。

WPF アプリケーションには、現在アクティブな NavigationServiceが複数ある場合があります。 詳細については、このトピックで後述 する「ナビゲーション ホスト 」を参照してください。

ナビゲーション サービスを使用したプログラムによるナビゲーション

NavigationServiceを使用してマークアップでナビゲーションが宣言によって実装される場合、Hyperlinkについて知る必要はありません。これは、Hyperlinkがユーザーの代わりにNavigationServiceを使用するためです。 つまり、 Hyperlink の直接または間接的な親がナビゲーション ホストである限り ( ナビゲーション ホストを参照)、 Hyperlink はナビゲーション ホストのナビゲーション サービスを検索して使用してナビゲーション要求を処理できます。

ただし、次のような NavigationService を直接使用する必要がある場合があります。

  • パラメーターなしのコンストラクターを使用して Page をインスタンス化する必要がある場合。

  • Pageに移動する前にプロパティを設定する必要がある場合。

  • 移動する必要がある Page は、実行時にのみ決定できます。

このような場合は、Navigate オブジェクトのNavigationService メソッドを呼び出して、プログラムによってナビゲーションを開始するコードを記述する必要があります。 これには、 NavigationServiceへの参照を取得する必要があります。

NavigationService への参照の取得

「ナビゲーション ホスト」セクションで説明されている理由から、WPF アプリケーションは複数のNavigationServiceを持つことができます。 つまり、コードには、通常、現在のNavigationServiceにアクセスするために使用されたNavigationServiceを見つける方法が必要です。 NavigationService static メソッドを呼び出すと、NavigationService.GetNavigationServiceへの参照を取得できます。 特定のNavigationServiceに移動したPageを取得するには、Page メソッドの引数としてGetNavigationServiceへの参照を渡します。 次のコードは、現在のNavigationServicePageを取得する方法を示しています。

using System.Windows.Navigation;
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = NavigationService.GetNavigationService(this);
' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = NavigationService.GetNavigationService(Me)

NavigationServicePageを検索するためのショートカットとして、PageNavigationServiceプロパティを実装します。 これを次の例に示します。

using System.Windows.Navigation;
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = this.NavigationService;
' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = Me.NavigationService

Pageは、NavigationServicePage イベントを発生させる場合にのみ、そのLoadedへの参照を取得できます。

プログラムによる Page オブジェクトへのナビゲーション

次の例は、 NavigationService を使用してプログラムで Pageに移動する方法を示しています。 移動する Page は、パラメーターなしのコンストラクターを 1 つだけ使用してインスタンス化できるため、プログラムによるナビゲーションが必要です。 パラメーターなしのコンストラクターを持つ Page を、次のマークアップとコードに示します。

<Page
    x:Class="SDKSample.PageWithNonDefaultConstructor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="PageWithNonDefaultConstructor">
  
  <!-- Content goes here -->
  
</Page>
using System.Windows.Controls;

namespace SDKSample
{
    public partial class PageWithNonDefaultConstructor : Page
    {
        public PageWithNonDefaultConstructor(string message)
        {
            InitializeComponent();

            this.Content = message;
        }
    }
}

Namespace SDKSample
    Partial Public Class PageWithNonDefaultConstructor
        Inherits Page
        Public Sub New(ByVal message As String)
            InitializeComponent()

            Me.Content = message
        End Sub
    End Class
End Namespace

パラメーターなしのコンストラクターを使用してPageに移動するPageを、次のマークアップとコードに示します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSNavigationPage">

  <Hyperlink Click="hyperlink_Click">
    Navigate to Page with Non-Default Constructor
  </Hyperlink>

</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class NSNavigationPage : Page
    {
        public NSNavigationPage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate the page to navigate to
            PageWithNonDefaultConstructor page = new PageWithNonDefaultConstructor("Hello!");

            // Navigate to the page, using the NavigationService
            this.NavigationService.Navigate(page);
        }
    }
}

Namespace SDKSample
    Partial Public Class NSNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Instantiate the page to navigate to
            Dim page As New PageWithNonDefaultConstructor("Hello!")

            ' Navigate to the page, using the NavigationService
            Me.NavigationService.Navigate(page)
        End Sub
    End Class
End Namespace

このHyperlinkPageをクリックすると、パラメーターなしのコンストラクターを使用して移動するPageをインスタンス化し、NavigationService.Navigate メソッドを呼び出すことによってナビゲーションが開始されます。 Navigate は、パック URI ではなく、 NavigationService が移動するオブジェクトへの参照を受け入れます。

パック URI を使用したプログラムによるナビゲーション

プログラムでパック URI を作成する必要がある場合 (実行時にのみパック URI を特定できる場合など)、 NavigationService.Navigate メソッドを使用できます。 これを次の例に示します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSUriNavigationPage">
  <Hyperlink Click="hyperlink_Click">Navigate to Page by Pack URI</Hyperlink>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class NSUriNavigationPage : Page
    {
        public NSUriNavigationPage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Create a pack URI
            Uri uri = new Uri("AnotherPage.xaml", UriKind.Relative);

            // Get the navigation service that was used to
            // navigate to this page, and navigate to
            // AnotherPage.xaml
            this.NavigationService.Navigate(uri);
        }
    }
}

Namespace SDKSample
    Partial Public Class NSUriNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Create a pack URI
            Dim uri As New Uri("AnotherPage.xaml", UriKind.Relative)

            ' Get the navigation service that was used to 
            ' navigate to this page, and navigate to 
            ' AnotherPage.xaml
            Me.NavigationService.Navigate(uri)
        End Sub
    End Class
End Namespace

現在のページの更新

Page プロパティに格納されているパック URI と同じパック URI を持つNavigationService.Sourceはダウンロードされません。 次の例に示すように、WPF で現在のページを強制的に再度ダウンロードするには、 NavigationService.Refresh メソッドを呼び出します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSRefreshNavigationPage">
 <Hyperlink Click="hyperlink_Click">Refresh this page</Hyperlink>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class NSRefreshNavigationPage : Page
    {

Namespace SDKSample
    Partial Public Class NSRefreshNavigationPage
        Inherits Page
        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Force WPF to download this page again
            this.NavigationService.Refresh();
        }
    }
}
        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Force WPF to download this page again
            Me.NavigationService.Refresh()
        End Sub
    End Class
End Namespace

ご確認のように、ナビゲーションを開始する方法は多数あります。 ナビゲーションが開始され、ナビゲーションの進行中に、 NavigationServiceによって実装される次のイベントを使用して、ナビゲーションを追跡して影響を与えることができます。

  • Navigating。 新しいナビゲーションが要求されたときに発生します。 ナビゲーションを取り消すために使用できます。

  • NavigationProgress。 ナビゲーションの進行状況情報を提供するために、ダウンロード中に定期的に発生します。

  • Navigated。 ページが見つけてダウンロードされたときに発生します。

  • NavigationStopped。 ( StopLoadingを呼び出して) ナビゲーションが停止したとき、または現在のナビゲーションの進行中に新しいナビゲーションが要求されたときに発生します。

  • NavigationFailed。 要求されたコンテンツへの移動中にエラーが発生したときに発生します。

  • LoadCompleted。 移動されたコンテンツが読み込まれて解析され、レンダリングが開始されたときに発生します。

  • FragmentNavigation。 コンテンツ フラグメントへのナビゲーションが開始されたときに発生します。これは次のようになります。

    • 目的のフラグメントが現在のコンテンツ内にある場合は直ちに。

    • ソース コンテンツが読み込まれた後、目的のフラグメントが異なるコンテンツにある場合。

ナビゲーション イベントは、次の図に示す順序で発生します。

ページ ナビゲーション フロー チャート

一般に、 Page はこれらのイベントを気にしません。 アプリケーションがそれらに関連している可能性が高く、そのため、これらのイベントも Application クラスによって発生します。

NavigationServiceイベントが発生するたびに、Application クラスは対応するイベントを発生させます。 FrameNavigationWindow は、それぞれのスコープ内のナビゲーションを検出するために同じイベントを提供します。

場合によっては、 Page がこれらのイベントに関心を持つ場合があります。 たとえば、 Page では、 NavigationService.Navigating イベントを処理して、それ自体から離れたナビゲーションを取り消すかどうかを判断できます。 これを次の例に示します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.CancelNavigationPage">
  <Button Click="button_Click">Navigate to Another Page</Button>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class CancelNavigationPage : Page
    {
        public CancelNavigationPage()
        {
            InitializeComponent();

            // Can only access the NavigationService when the page has been loaded
            this.Loaded += new RoutedEventHandler(CancelNavigationPage_Loaded);
            this.Unloaded += new RoutedEventHandler(CancelNavigationPage_Unloaded);
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Force WPF to download this page again
            this.NavigationService.Navigate(new Uri("AnotherPage.xaml", UriKind.Relative));
        }

        void CancelNavigationPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
        }

        void CancelNavigationPage_Unloaded(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigating -= new NavigatingCancelEventHandler(NavigationService_Navigating);
        }

        void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            // Does the user really want to navigate to another page?
            MessageBoxResult result;
            result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo);

            // If the user doesn't want to navigate away, cancel the navigation
            if (result == MessageBoxResult.No) e.Cancel = true;
        }
    }
}

Namespace SDKSample
    Partial Public Class CancelNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()

            ' Can only access the NavigationService when the page has been loaded
            AddHandler Loaded, AddressOf CancelNavigationPage_Loaded
            AddHandler Unloaded, AddressOf CancelNavigationPage_Unloaded
        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Force WPF to download this page again
            Me.NavigationService.Navigate(New Uri("AnotherPage.xaml", UriKind.Relative))
        End Sub

        Private Sub CancelNavigationPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            AddHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
        End Sub

        Private Sub CancelNavigationPage_Unloaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            RemoveHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
        End Sub

        Private Sub NavigationService_Navigating(ByVal sender As Object, ByVal e As NavigatingCancelEventArgs)
            ' Does the user really want to navigate to another page?
            Dim result As MessageBoxResult
            result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo)

            ' If the user doesn't want to navigate away, cancel the navigation
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End Sub
    End Class
End Namespace

前の例のように、 Pageのナビゲーション イベントにハンドラーを登録する場合は、イベント ハンドラーの登録を解除する必要もあります。 そうしないと、WPF ナビゲーションがジャーナルを使用して Page ナビゲーションを記憶する方法に関して副作用が発生する可能性があります。

ジャーナルを用いたナビゲーションの記憶

WPF では、2 つのスタックを使用して、移動元のページ (バック スタックと前方スタック) を記憶します。 現在の Page から新しい Page に移動するか、既存の Pageに転送すると、現在の Pageバック スタックに追加されます。 現在の Page から前の Pageに戻ると、現在の Page前方スタックに追加されます。 バック スタック、前方スタック、およびそれらを管理する機能は、まとめてジャーナルと呼ばれます。 バック スタックと前方スタックの各項目は、 JournalEntry クラスのインスタンスであり、 ジャーナル エントリと呼ばれます。

概念的には、履歴は Internet Explorer の [戻る ] ボタンと [進む ] ボタンと同じように動作します。 これらを次の図に示します。

[戻る] ボタンと [進む] ボタンは、[

Internet Explorer でホストされている XBAP の場合、WPF はジャーナルを Internet Explorer のナビゲーション UI に統合します。 これにより、ユーザーは Internet Explorer の [ 戻る]、[ 転送]、[ 最近使ったページ ] ボタンを使用して、XBAP 内のページ間を移動できます。

重要

Internet Explorer では、ユーザーが XBAP との間を移動して戻るときに、保持されなかったページのジャーナル エントリのみが履歴に保持されます。 ページを維持する方法については、このトピックで後述 する「ページの有効期間」と「ジャーナル 」を参照してください。

既定では、Internet Explorer の Page] リストに表示される各のテキストは、Pageの URI です。 多くの場合、これはユーザーにとって特に意味がありません。 幸い、次のいずれかのオプションを使用してテキストを変更できます。

  1. アタッチされた JournalEntry.Name 属性値。

  2. Page.Title属性値。

  3. 現在のPage.WindowTitleの URI と Page属性値。

  4. 現在の Pageの URI。 (既定値)

オプションが一覧表示される順序は、テキストを検索するための優先順位と一致します。 たとえば、 JournalEntry.Name が設定されている場合、その他の値は無視されます。

次の例では、 Page.Title 属性を使用して、履歴エントリに表示されるテキストを変更します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.PageWithTitle"
    Title="This is the title of the journal entry for this page.">
</Page>
using System.Windows.Controls;

namespace SDKSample
{
    public partial class PageWithTitle : Page
    {

Namespace SDKSample
    Partial Public Class PageWithTitle
        Inherits Page
    }
}
    End Class
End Namespace

ユーザーは Internet Explorer の [戻る]、[ 進む]、[ 最近使ったページ ] を使用してジャーナルを移動できますが、WPF によって提供される宣言型およびプログラム的なメカニズムの両方を使用してジャーナル内を移動することもできます。 これを行う理由の 1 つは、ページにカスタム ナビゲーション UI を提供することです。

NavigationCommandsによって公開されるナビゲーション コマンドを使用して、ジャーナル ナビゲーション サポートを宣言によって追加できます。 次の例では、 BrowseBack ナビゲーション コマンドを使用する方法を示します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NavigationCommandsPage">
<Hyperlink Command="NavigationCommands.BrowseBack">Back</Hyperlink>
<Hyperlink Command="NavigationCommands.BrowseForward">Forward</Hyperlink>
</Page>

NavigationService クラスの次のいずれかのメンバーを使用して、プログラムによってジャーナル内を移動できます。

ジャーナルは、このトピックで後述する「ナビゲーション履歴を使用 したコンテンツ状態の保持 」で説明されているように、プログラムで操作することもできます。

ページの有効期間とジャーナル

グラフィックス、アニメーション、メディアなど、リッチ コンテンツを含む複数のページを含む XBAP について考えてみましょう。 このようなページのメモリ占有領域は、特にビデオとオーディオ メディアが使用されている場合に非常に大きくなる可能性があります。 ジャーナルが移動されたページを "記憶" していることを考えると、このような XBAP は大量のメモリをすばやく消費する可能性があります。

このため、ジャーナルの既定の動作は、Page オブジェクトへの参照ではなく、各ジャーナル エントリにPageメタデータを格納することです。 ジャーナル エントリに移動すると、その Page メタデータを使用して、指定した Pageの新しいインスタンスが作成されます。 その結果、移動される各 Page には、次の図に示す有効期間があります。

[ページの有効期間]

既定のジャーナリング動作を使用するとメモリ消費量を節約できますが、ページごとのレンダリングパフォーマンスが低下する可能性があります。コンテンツが多い場合は特に、 Page の再立に時間がかかる場合があります。 ジャーナルに Page インスタンスを保持する必要がある場合は、それを行うための 2 つの手法に基づいて描画できます。 まず、Page メソッドを呼び出すことによって、プログラムでNavigationService.Navigate オブジェクトに移動できます。

次に、 プロパティを (既定値は ) に設定することで、WPF がジャーナル内ののインスタンスを保持するように指定できます。 次の例に示すように、マークアップで宣言によって KeepAlive を設定できます。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.KeepAlivePage"
    KeepAlive="True">
  
  An instance of this page is stored in the journal.
  
</Page>

維持される Page の有効期間は、そうでないものとは微妙に異なります。 最初に維持される Page に移動すると、アクティブにされていない Page と同様にインスタンス化されます。 ただし、 Page のインスタンスはジャーナルに保持されるため、ジャーナルに残っている限りインスタンス化されません。 そのため、 Page に、 Page が移動するたびに呼び出す必要がある初期化ロジックがある場合は、コンストラクターから Loaded イベントのハンドラーに移動する必要があります。 次の図に示すように、Loaded へ移動するたびに Unloaded イベントが、Loaded から移動するたびに イベントが引き続き発生します。

Loaded イベントと Unloaded イベントが発生すると

Pageが維持されない場合は、次のいずれかの操作を行わないでください。

  • その参照またはその一部を格納します。

  • 実装されていないイベントにイベントハンドラーを登録します。

これらのいずれかを実行すると、ジャーナルから削除された後でも、 Page を強制的にメモリに保持する参照が作成されます。

一般に、Pageを維持しないという既定のPage動作を優先する必要があります。 ただし、これには、次のセクションで説明する状態への影響があります。

ナビゲーション履歴を使用したコンテンツの状態の保持

Pageが維持されず、ユーザーからデータを収集するコントロールがある場合、ユーザーがPageに移動したり戻ったりすると、データはどうなりますか。 ユーザー エクスペリエンスの観点から、ユーザーは以前に入力したデータが表示されることを期待する必要があります。 残念ながら、各ナビゲーションで Page の新しいインスタンスが作成されるため、データを収集したコントロールは再インスタンス化され、データは失われます。

さいわい、ジャーナルでは、コントロール データを含む Page ナビゲーション全体のデータを記憶するためのサポートが提供されます。 具体的には、各 Page のジャーナル エントリは、関連付けられている Page 状態の一時コンテナーとして機能します。 次の手順では、Page を操作する際にこのサポートがどのように使用されるかについて説明します。

  1. 現在の Page のエントリが履歴に追加されます。

  2. Pageの状態は、そのページのジャーナル エントリと共に格納され、バック スタックに追加されます。

  3. 新しい Page に移動します。

ページ Page に移動し、履歴を使用すると、次の手順が実行されます。

  1. Page (バック スタックの最上位のジャーナル エントリ) がインスタンス化されます。

  2. Pageは、Pageのジャーナル エントリと共に格納された状態で更新されます。

  3. Pageに戻ります。

WPF では、 Pageで次のコントロールが使用されている場合、このサポートが自動的に使用されます。

Pageがこれらのコントロールを使用している場合、次の図の Page] で示すように、 ナビゲーション全体で入力されたデータが記憶されますListBox

入力されたデータの状態を記憶するコントロールを含む

Pageに上記のリスト以外のコントロールがある場合、または状態がカスタム オブジェクトに格納されている場合は、Pageナビゲーション全体でジャーナルに状態を記憶させるコードを記述する必要があります。

Pageナビゲーション全体で小さな状態を記憶する必要がある場合は、DependencyProperty メタデータ フラグを使用して構成された依存関係プロパティ (FrameworkPropertyMetadata.Journalを参照) を使用できます。

Pageがナビゲーション全体で記憶する必要がある状態が複数のデータで構成されている場合は、1 つのクラスに状態をカプセル化し、IProvideCustomContentState インターフェイスを実装する方がコードの負荷が少なくなる場合があります。

Page自体から移動せずに、1 つのPageのさまざまな状態を移動する必要がある場合は、IProvideCustomContentStateNavigationService.AddBackEntryを使用できます。

クッキー

WPF アプリケーションでデータを格納できるもう 1 つの方法は、 SetCookie メソッドと GetCookie メソッドを使用して作成、更新、削除される Cookie を使用することです。 WPF で作成できる Cookie は、他の種類の Web アプリケーションが使用する Cookie と同じです。Cookie は、アプリケーション セッション中またはアプリケーション セッション間でクライアント コンピューター上のアプリケーションによって格納される任意のデータです。 Cookie データは、通常、名前と値のペアの形式を次の形式で受け取ります。

名前=価値

データが SetCookieに渡されると、Cookie を設定する場所の Uri と共に、Cookie がメモリ内に作成され、現在のアプリケーション セッションの期間中のみ使用できます。 この種類の Cookie は、 セッション Cookie と呼ばれます。

アプリケーション セッション間で Cookie を格納するには、次の形式を使用して、有効期限を Cookie に追加する必要があります。

NAME=価値; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT

有効期限が設定された Cookie は、Cookie の有効期限が切れるまで、現在の Windows インストールの一時インターネット ファイル フォルダーに格納されます。 このような Cookie は、アプリケーション セッション間で保持されるため、 永続的な Cookie と呼ばれます。

セッションと永続的な Cookie の両方を取得する場合は、 GetCookie メソッドを呼び出し、cookie が設定された場所の UriSetCookie メソッドで渡します。

WPF で Cookie がサポートされる方法の一部を次に示します。

  • WPF スタンドアロン アプリケーションと XBAP は、Cookie の作成と管理の両方を行うことができます。

  • XBAP によって作成された Cookie には、ブラウザーからアクセスできます。

  • 同じドメインの XBAP は、Cookie を作成して共有できます。

  • 同じドメインの XBAP ページと HTML ページは、Cookie を作成して共有できます。

  • Cookie は、XBAP とルーズ XAML ページが Web 要求を行うときにディスパッチされます。

  • IFRAMES でホストされている最上位レベルの XBAP と XBAP の両方が Cookie にアクセスできます。

  • WPF での Cookie のサポートは、サポートされているすべてのブラウザーで同じです。

  • Internet Explorer では、Cookie に関連する P3P ポリシーは、特にファースト パーティおよびサード パーティの XBAP に関して WPF によって受け入れられます。

構造化ナビゲーション

ある Page から別のにデータを渡す必要がある場合は、 Pageのパラメーターなしのコンストラクターにデータを引数として渡すことができます。 この手法を使用する場合は、 Page を維持する必要があることに注意してください。そうでない場合、次に Pageに移動すると、WPF はパラメーターなしのコンストラクターを使用して Page を再インスタンス化します。

または、 Page は、渡す必要があるデータで設定されたプロパティを実装できます。 ただし、PagePage にデータを戻す必要があると、処理が難しくなります。 問題は、ナビゲーションが移動後に Page が返されることを保証するためのメカニズムをネイティブにサポートしていないということです。 基本的に、ナビゲーションは呼び出し/戻りセマンティクスをサポートしていません。 この問題を解決するために、WPF には、予測可能で構造化された方法でPageFunction<T>が確実に返されるようにするために使用できるPage クラスが用意されています。 詳細については、「 構造化ナビゲーションの概要」を参照してください。

NavigationWindow クラス

ここまでは、ナビゲーション 可能なコンテンツを含むアプリケーションの構築に使用する可能性が最も高いナビゲーション サービスの色域を確認しました。 これらのサービスは XBAP のコンテキストで説明されましたが、XBAP に限定されるわけではありません。 最新のオペレーティング システムと Windows アプリケーションでは、最新のユーザーのブラウザー エクスペリエンスを利用して、ブラウザー スタイルのナビゲーションをスタンドアロン アプリケーションに組み込みます。 たとえば、次のような場合です。

  • 単語類義語辞典: 単語の選択肢に移動します。

  • エクスプローラー: ファイルとフォルダーを移動します。

  • ウィザード: 複雑なタスクを複数のページに分割し、その間を移動できます。 たとえば、Windows の機能の追加と削除を処理する Windows コンポーネント ウィザードがあります。

ブラウザー スタイルのナビゲーションをスタンドアロン アプリケーションに組み込むには、 NavigationWindow クラスを使用できます。 NavigationWindowWindow から派生し、XBAP が提供するのと同じナビゲーションをサポートして拡張します。 NavigationWindowは、スタンドアロン アプリケーションのメイン ウィンドウとして、またはダイアログ ボックスなどのセカンダリ ウィンドウとして使用できます。

WPF のほとんどの最上位クラス (NavigationWindowWindowなど) と同様に、Pageを実装するには、マークアップと分離コードの組み合わせを使用します。 これを次の例に示します。

<NavigationWindow
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MainWindow" 
    Source="HomePage.xaml"/>
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class MainWindow : NavigationWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

Namespace SDKSample
    Partial Public Class MainWindow
        Inherits NavigationWindow
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace

このコードでは、NavigationWindowを開くと、Page (HomePage.xaml) に自動的に移動するNavigationWindowが作成されます。 NavigationWindowがメイン アプリケーション ウィンドウの場合は、StartupUri属性を使用して起動できます。 これは、次のマークアップに示されています。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

次の図は、スタンドアロン アプリケーションのメイン ウィンドウとしての NavigationWindow を示しています。

メイン ウィンドウ

図から、前の例のNavigationWindow実装コードで設定されていない場合でも、NavigationWindowにタイトルがあることがわかります。 代わりに、次のコードに示すように、 WindowTitle プロパティを使用してタイトルを設定します。

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Title="Home Page"
    WindowTitle="NavigationWindow">
</Page>

WindowWidthプロパティとWindowHeightプロパティを設定すると、NavigationWindowにも影響します。

通常、動作またはその外観をカスタマイズする必要がある場合は、独自の NavigationWindow を実装します。 どちらも行わない場合は、ショートカットを使用できます。 スタンドアロン アプリケーションでPageのパック URI をStartupUriとして指定した場合、ApplicationNavigationWindowをホストするPageを自動的に作成します。 次のマークアップは、これを有効にする方法を示しています。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

ダイアログ ボックスなどのセカンダリ アプリケーション ウィンドウを NavigationWindowにする場合は、次の例のコードを使用して開くことができます。

// Open a navigation window as a dialog box
NavigationWindowDialogBox dlg = new NavigationWindowDialogBox();
dlg.Source = new Uri("HomePage.xaml", UriKind.Relative);
dlg.Owner = this;
dlg.ShowDialog();
' Open a navigation window as a dialog box
Dim dlg As New NavigationWindowDialogBox()
dlg.Source = New Uri("HomePage.xaml", UriKind.Relative)
dlg.Owner = Me
dlg.ShowDialog()

次の図に結果を示します。

ダイアログ ボックス

ご覧のように、 NavigationWindow には Internet Explorer スタイルの [戻る ] ボタンと [進む ] ボタンが表示され、ユーザーは履歴を移動できます。 これらのボタンは、次の図に示すように、同じユーザー エクスペリエンスを提供します。

ナビゲーションウィンドウでの [戻る] ボタンと [進む] ボタン

ページに独自のジャーナル ナビゲーション サポートと UI が用意されている場合は、 プロパティの値を に設定することで、NavigationWindow表示される ShowsNavigationUI] ボタンと false] ボタンを非表示にすることができます。

または、WPF のカスタマイズ サポートを使用して、 NavigationWindow 自体の UI を置き換えることができます。

Frame クラス

ブラウザーと NavigationWindow はどちらも、ナビゲーション可能なコンテンツをホストするウィンドウです。 場合によっては、アプリケーションには、ウィンドウ全体でホストする必要のないコンテンツがあります。 代わりに、このようなコンテンツは他のコンテンツ内でホストされます。 Frame クラスを使用して、ナビゲーション可能なコンテンツを他のコンテンツに挿入できます。 Frame は、 NavigationWindow および XBAP と同じサポートを提供します。

次の例は、Frame要素を使用して宣言によってPageFrameを追加する方法を示しています。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">
<Frame Source="FramePage1.xaml" />
</Page>

このマークアップは、Sourceが最初に移動するFrameのパック URI を使用して、Page要素のFrame属性を設定します。 次の図は、複数のページ間を移動したPageが含まれているFrameがある XBAP を示しています。

複数のページ間を移動したフレーム。複数のページ

Frameのコンテンツ内だけでPageを使わなくてもかまいません。 また、Frameのコンテンツ内でWindowをホストすることも一般的です。

既定では、 Frame は、別の仕訳帳がない場合にのみ独自の仕訳帳を使用します。 FrameNavigationWindowまたは XBAP 内でホストされるコンテンツの一部である場合、Frameは、NavigationWindowまたは XBAP に属するジャーナルを使用します。 ただし、場合によっては、 Frame が独自のジャーナルを担当する必要があります。 これを行う 1 つの理由は、 Frameによってホストされているページ内のジャーナル ナビゲーションを許可することです。 これを次の図に示します。

フレームとページの図

この場合、FrameJournalOwnership プロパティをFrameに設定することで、独自のジャーナルを使用するようにOwnsJournalを構成できます。 これは、次のマークアップに示されています。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">
<Frame Source="FramePage1.xaml" JournalOwnership="OwnsJournal" />
</Page>

次の図は、独自のジャーナルを使用する Frame 内を移動する効果を示しています。

独自のジャーナルを使用するフレーム

ジャーナル エントリは、Internet Explorer ではなく、 Frameのナビゲーション UI によって表示されます。

FrameWindowでホストされているコンテンツの一部である場合、Frameは独自のジャーナルを使用し、その結果、独自のナビゲーション UI を表示します。

ユーザー エクスペリエンスで、ナビゲーション UI を表示せずに独自のジャーナルを提供するために Frame が必要な場合は、 NavigationUIVisibilityHidden に設定することで、ナビゲーション UI を非表示にすることができます。 これは、次のマークアップに示されています。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">
<Frame 
  Source="FramePage1.xaml" 
  JournalOwnership="OwnsJournal" 
  NavigationUIVisibility="Hidden" />
</Page>

Frame および NavigationWindow は、ナビゲーション ホストと呼ばれるクラスです。 ナビゲーション ホストは、コンテンツに移動して表示できるクラスです。 これを実現するために、各ナビゲーション ホストは独自の NavigationService とジャーナルを使用します。 ナビゲーション ホストの基本的な構造を次の図に示します。

ナビゲーター図

基本的に、これにより、 NavigationWindowFrame は、ブラウザーでホストされるときに XBAP が提供するのと同じナビゲーション サポートを提供できます。

ナビゲーション ホストは、 NavigationService とジャーナルを使用するだけでなく、 NavigationService 実装するのと同じメンバーを実装します。 これを次の図に示します。

フレームおよびナビゲーションウィンドウ内のジャーナル

これにより、それらに対して直接ナビゲーション サポートをプログラムできます。 これは、FrameでホストされているWindowのカスタム ナビゲーション UI を提供する必要がある場合に考慮できます。 さらに、どちらの型も、 BackStack (NavigationWindow.BackStackFrame.BackStack) や ForwardStack (NavigationWindow.ForwardStackFrame.ForwardStack) など、ナビゲーション関連の追加メンバーを実装します。これにより、バック スタックとフォワード スタックのジャーナル エントリをそれぞれ列挙できます。

前述のように、1 つのアプリケーション内に複数のジャーナルを存在させることができます。 次の図は、このような状況の例を示しています。

1 つのアプリケーション内の複数のジャーナル

このトピックでは、Page とパック XBAP を使用して、WPF のさまざまなナビゲーション機能を示しました。 ただし、アプリケーションにコンパイルされるPageは、ナビゲートできる唯一のコンテンツではなく、また、パックされたXBAPがコンテンツを識別する唯一の方法でもありません。

このセクションで示すように、ルーズ XAML ファイル、HTML ファイル、オブジェクトに移動することもできます。

ルーズ XAML ファイルは、次の特性を持つファイルです。

  • XAML のみを含みます (つまり、コードは含まない)。

  • 適切な名前空間宣言があります。

  • .xaml ファイル名拡張子を持ちます。

たとえば、緩い XAML ファイル Person.xaml として格納される次のコンテンツについて考えてみましょう。

<!-- Person.xaml -->
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <TextBlock FontWeight="Bold">Name:</TextBlock>
  <TextBlock>Nancy Davolio</TextBlock>
  <LineBreak />
  <TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
  <TextBlock>Yellow</TextBlock>
</TextBlock>

ファイルをダブルクリックすると、ブラウザーが開き、コンテンツに移動して表示されます。 これを次の図に示します。

Person.XAML ファイル内のコンテンツの表示 Person.XAML

次の方法で、緩やかな XAML ファイルを表示できます。

  • ローカル コンピューター、イントラネット、またはインターネット上の Web サイト。

  • 汎用名前付け規則 (UNC) ファイル共有。

  • ローカル ディスク。

緩い XAML ファイルは、ブラウザーのお気に入りに追加することも、ブラウザーのホーム ページにすることもできます。

緩やかな XAML ページの発行と起動の詳細については、「 WPF アプリケーションのデプロイ」を参照してください。

緩やかな XAML に関する制限の 1 つは、部分信頼で安全に実行できるコンテンツのみをホストできることです。 たとえば、 Window は、緩やかな XAML ファイルのルート要素にすることはできません。 詳細については、「 WPF 部分信頼セキュリティ」を参照してください。

ご期待のとおり、HTML に移動することもできます。 http スキームを使用する URI を指定するだけでかまいません。 たとえば、次の XAML は、HTML ページに移動する Frame を示しています。

<Frame Source="http://www.microsoft.com/default.aspx" />

HTML に移動するには、特別なアクセス許可が必要です。 たとえば、インターネット ゾーンの部分信頼セキュリティ サンドボックスで実行されている XBAP から移動することはできません。 詳細については、「 WPF 部分信頼セキュリティ」を参照してください。

WebBrowser コントロールは、HTML ドキュメントのホスティング、ナビゲーション、スクリプト/マネージド コードの相互運用性をサポートします。 WebBrowser コントロールの詳細については、WebBrowserを参照してください。

Frameと同様に、WebBrowserを使用して HTML に移動するには、特別なアクセス許可が必要です。 たとえば、部分信頼アプリケーションから、元のサイトにある HTML にのみ移動できます。 詳細については、「 WPF 部分信頼セキュリティ」を参照してください。

カスタム オブジェクトとして格納されているデータがある場合、そのデータを表示する 1 つの方法は、それらのオブジェクトにバインドされたコンテンツを含む Page を作成することです ( データ バインディングの概要を参照)。 オブジェクトを表示するためだけにページ全体を作成するオーバーヘッドが不要な場合は、代わりにそれらに直接移動できます。

次のコードで実装されている Person クラスについて考えてみましょう。

using System.Windows.Media;

namespace SDKSample
{
    public class Person
    {
        string name;
        Color favoriteColor;

        public Person() { }
        public Person(string name, Color favoriteColor)
        {
            this.name = name;
            this.favoriteColor = favoriteColor;
        }

        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        public Color FavoriteColor
        {
            get { return this.favoriteColor; }
            set { this.favoriteColor = value; }
        }
    }
}

Namespace SDKSample
    Public Class Person
        Private _name As String
        Private _favoriteColor As Color

        Public Sub New()
        End Sub
        Public Sub New(ByVal name As String, ByVal favoriteColor As Color)
            Me._name = name
            Me._favoriteColor = favoriteColor
        End Sub

        Public Property Name() As String
            Get
                Return Me._name
            End Get
            Set(ByVal value As String)
                Me._name = value
            End Set
        End Property

        Public Property FavoriteColor() As Color
            Get
                Return Me._favoriteColor
            End Get
            Set(ByVal value As Color)
                Me._favoriteColor = value
            End Set
        End Property
    End Class
End Namespace

それに移動するには、次のコードで示すように、 NavigationWindow.Navigate メソッドを呼び出します。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.HomePage"
  WindowTitle="Page that Navigates to an Object">
<Hyperlink Name="hyperlink" Click="hyperlink_Click">
  Navigate to Nancy Davolio
</Hyperlink>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace SDKSample
{
    public partial class HomePage : Page
    {
        public HomePage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            Person person = new Person("Nancy Davolio", Colors.Yellow);
            this.NavigationService.Navigate(person);
        }
    }
}

Namespace SDKSample
    Partial Public Class HomePage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim person As New Person("Nancy Davolio", Colors.Yellow)
            Me.NavigationService.Navigate(person)
        End Sub
    End Class
End Namespace

次の図に結果を示します。

クラスに移動するページ オブジェクトに移動

この図から、役に立つものは何も表示されていないことがわかります。 実際、表示される値は ToString オブジェクトの メソッドの戻り値です。既定では、WPF がオブジェクトを表すために使用できる唯一の値です。 ToStringメソッドをオーバーライドして、より意味のある情報を返すようにすることもできますが、文字列値のみが返されます。 WPF のプレゼンテーション機能を利用できる手法の 1 つは、データ テンプレートを使用することです。 WPF が特定の型のオブジェクトに関連付けることができるデータ テンプレートを実装できます。 次のコードは、 Person オブジェクトのデータ テンプレートを示しています。

<Application
    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.App"
    StartupUri="HomePage.xaml">

  <Application.Resources>

    <!-- Data Template for the Person Class -->
    <DataTemplate DataType="{x:Type local:Person}">
      <TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <TextBlock FontWeight="Bold">Name:</TextBlock>
        <TextBlock Text="{Binding Path=Name}" />
        <LineBreak />
        <TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
        <TextBlock Text="{Binding Path=FavoriteColor}" />
      </TextBlock>
    </DataTemplate>
    
  </Application.Resources>

</Application>

ここでは、データ テンプレートは、Person属性のx:Typeマークアップ拡張を使用して、DataType型に関連付けられています。 その後、データ テンプレート TextBlock 要素 ( TextBlock参照) を Person クラスのプロパティにバインドします。 次の図は、 Person オブジェクトの更新された外観を示しています。

データ テンプレートを持つクラスに移動する データ テンプレート

この手法の利点は、データ テンプレートを再利用してアプリケーション内の任意の場所にオブジェクトを一貫して表示できることによって得られる一貫性です。

データ テンプレートの詳細については、「 データ テンプレートの概要」を参照してください。

安全

WPF ナビゲーションのサポートにより、XBAP をインターネット経由で移動でき、アプリケーションでサード パーティのコンテンツをホストできます。 アプリケーションとユーザーの両方を有害な動作から保護するために、WPF には、 セキュリティWPF 部分信頼セキュリティで説明されているさまざまなセキュリティ機能が用意されています。

こちらも参照ください