次の方法で共有


WPF でのパック URI

Windows Presentation Foundation (WPF) では、UNIFORM Resource Identifier (URI) を使用して、次のようなさまざまな方法でファイルを識別して読み込みます。

  • アプリケーションの初回起動時に表示するユーザー インターフェイス (UI) の指定。

  • イメージの読み込み。

  • ページに移動する。

  • 実行可能でないデータ ファイルの読み込み。

さらに、URI を使用して、次のようなさまざまな場所からファイルを識別して読み込むことができます。

  • 現在のアセンブリ。

  • 参照対象のアセンブリ。

  • アセンブリを基準とする位置。

  • アプリケーションの配信元サイト。

これらの場所からこれらの種類のファイルを識別して読み込むための一貫したメカニズムを提供するために、WPF は パック URI スキームの拡張性を利用します。 このトピックでは、マークアップとコードの両方からパック URI を使用する方法を示す前に、スキームの概要、さまざまなシナリオでパック URI を構築する方法、絶対 URI と相対 URI と URI 解決について説明します。

パック URI スキーム

パック URI スキームは、コンテンツを整理および識別するためのモデルを記述する Open Packaging Conventions (OPC) 仕様で使用されます。 このモデルの重要な要素はパッケージとパーツであり、 パッケージ は 1 つ以上の論理 パーツの論理コンテナーです。 次の図は、この概念を示しています。

パッケージとパーツの図

OPC 仕様では、パーツを識別するために、RFC 2396 (Uniform Resource Identifiers (URI): Generic Syntax) の拡張性を利用してパック URI スキームを定義します。

URI によって指定されるスキームは、プレフィックスによって定義されます。http、ftp、および file はよく知られている例です。 パック URI スキームでは、スキームとして "pack" が使用され、機関とパスの 2 つのコンポーネントが含まれています。 パック URI の形式を次に示します。

pack:// authority/path

権限は、パーツが含まれるパッケージの種類を指定し、パスはパッケージ内のパーツの場所を指定します。

この概念を次の図に示します。

パッケージ、権限、パス間の関係

パッケージとパーツは、アプリケーションとファイルに似ています。アプリケーション (パッケージ) には、次のような 1 つ以上のファイル (パーツ) を含めることができます。

  • ローカル アセンブリにコンパイルされるリソース ファイル。

  • 参照されるアセンブリにコンパイルされるリソース ファイル。

  • 参照アセンブリにコンパイルされるリソース ファイル。

  • コンテンツ ファイル。

  • 元のサイト ファイル。

これらの種類のファイルにアクセスするために、WPF では、application:/// と siteoforigin:/// の 2 つの機関がサポートされています。 application:/// 機関は、リソース ファイルやコンテンツ ファイルなど、コンパイル時に認識されるアプリケーション データ ファイルを識別します。 siteoforigin:/// 権限は、元のサイトファイルを特定します。 各権限のスコープを次の図に示します。

パック URI 図

パック URI の機関コンポーネントは、パッケージを指す埋め込み URI であり、RFC 2396 に準拠している必要があります。 さらに、"/" 文字は "," 文字に置き換える必要があり、"%" や "?" などの予約文字はエスケープする必要があります。 詳細については、OPC を参照してください。

以降のセクションでは、これら 2 つの機関を使用して、リソース、コンテンツ、および配信元サイト のファイルを識別するための適切なパスと組み合わせてパック URI を構築する方法について説明します。

リソース ファイル パック URI

リソース ファイルは MSBuild Resource 項目として構成され、アセンブリにコンパイルされます。 WPF では、ローカル アセンブリにコンパイルされるか、ローカル アセンブリから参照されるアセンブリにコンパイルされるリソース ファイルを識別するために使用できるパック URI の構築がサポートされています。

ローカル アセンブリ リソース ファイル

ローカル アセンブリにコンパイルされるリソース ファイルのパック URI は、次の権限とパスを使用します。

  • 権限: application:///。

  • パス: ローカル アセンブリ プロジェクト フォルダーのルートを基準とした、リソース ファイルの名前 (パスを含む)。

次の例は、ローカル アセンブリのプロジェクト フォルダーのルートにある XAML リソース ファイルのパック URI を示しています。

pack://application:,,,/ResourceFile.xaml

次の例は、ローカル アセンブリのプロジェクト フォルダーのサブフォルダーにある XAML リソース ファイルのパック URI を示しています。

pack://application:,,,/Subfolder/ResourceFile.xaml

参照アセンブリ リソース ファイル

参照アセンブリにコンパイルされるリソース ファイルのパック URI は、次の権限とパスを使用します。

  • 権限: application:///。

  • パス: 参照アセンブリにコンパイルされるリソース ファイルの名前。 パスは次の形式に準拠している必要があります。

    AssemblyShortName{;バージョン]{;PublicKey];component/Path

    • AssemblyShortName: 参照されるアセンブリの短い名前。

    • ;バージョン [省略可能]: リソース ファイルを含む参照アセンブリのバージョン。 これは、同じ短い名前の複数の参照アセンブリが読み込まれるときに使用されます。

    • ;PublicKey [省略可能]: 参照アセンブリの署名に使用された公開キー。 これは、同じ短い名前の複数の参照アセンブリが読み込まれるときに使用されます。

    • ;component: 参照されるアセンブリがローカル アセンブリから参照されることを指定します。

    • /Path: 参照されるアセンブリのプロジェクト フォルダーのルートを基準とした、リソース ファイルの名前 (パスを含む)。

次の例は、参照先アセンブリのプロジェクト フォルダーのルートにある XAML リソース ファイルのパック URI を示しています。

pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml

次の例は、参照先アセンブリのプロジェクト フォルダーのサブフォルダーにある XAML リソース ファイルのパック URI を示しています。

pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

次の例は、参照先のバージョン固有のアセンブリのプロジェクト フォルダーのルート フォルダーにある XAML リソース ファイルのパック URI を示しています。

pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml

参照されるアセンブリ リソース ファイルのパック URI 構文は、application:/// 機関でのみ使用できることに注意してください。 たとえば、WPF では次の機能はサポートされていません。

pack://siteoforigin:,,,/SomeAssembly;component/ResourceFile.xaml

コンテンツ ファイル パック URI

コンテンツ ファイルのパック URI は、次の機関とパスを使用します。

  • 権限: application:///。

  • パス: アプリケーションのメイン実行可能アセンブリのファイル システムの場所に対する相対パスを含む、コンテンツ ファイルの名前。

次の例は、実行可能アセンブリと同じフォルダーにある XAML コンテンツ ファイルのパック URI を示しています。

pack://application:,,,/ContentFile.xaml

次の例は、アプリケーションの実行可能アセンブリに対する相対サブフォルダーにある XAML コンテンツ ファイルのパック URI を示しています。

pack://application:,,,/Subfolder/ContentFile.xaml

HTML コンテンツ ファイルに移動できません。 URI スキームでは、元のサイトにある HTML ファイルへのナビゲーションのみがサポートされます。

オリジンサイトパックURI群

配信元サイト ファイルのパック URI は、次の機関とパスを使用します。

  • 権限: siteoforigin:///。

  • パス: 実行可能アセンブリの起動元の場所に対する相対パスを含む、元のサイト ファイルの名前。

次の例は、実行可能アセンブリの起動元の場所に格納されている、XAML の起点サイト ファイルのパック URI を示しています。

pack://siteoforigin:,,,/SiteOfOriginFile.xaml

次の例は、アプリケーションの実行可能アセンブリの起動元の場所を基準とするサブフォルダーに格納されている、XAML の元のサイト ファイルのパック URI を示しています。

pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml

ページ ファイル

MSBuild Page 項目として構成された XAML ファイルは、リソース ファイルと同じ方法でアセンブリにコンパイルされます。 そのため、MSBuild Page 項目は、リソース ファイルのパック URI を使用して識別できます。

MSBuild として一般的に構成される XAML ファイルの種類Page 項目には、ルート要素として次のいずれかが含まれます。

絶対パック URI と相対パック URI

完全修飾パック URI にはスキーム、権限、パスが含まれており、絶対パック URI と見なされます。 開発者にとって簡略化された XAML 要素では、通常、パスのみを含む相対パック URI を使用して適切な属性を設定できます。

たとえば、ローカル アセンブリ内のリソース ファイルの絶対パック URI を次に示します。

pack://application:,,,/ResourceFile.xaml

このリソース ファイルを参照する相対パック URI は次のようになります。

/ResourceFile.xaml

起点サイト ファイルはアセンブリに関連付けられていないため、絶対パック URI でのみ参照できます。

既定では、相対パック URI は、参照を含むマークアップまたはコードの場所を基準として考慮されます。 ただし、先頭にバックスラッシュが使用されている場合、相対パック URI 参照はアプリケーションのルートを基準として解釈されます。 たとえば、次のプロジェクト構造を考えてみましょう。

App.xaml

Page2.xaml

\SubFolder

+ Page1.xaml

+ Page2.xaml

Page1.xaml に Root\SubFolder\Page2.xaml を参照する URI が含まれている場合、参照では次の相対パック URI を使用できます。

Page2.xaml

Page1.xaml に Root\Page2.xaml を参照する URI が含まれている場合、参照では次の相対パック URI を使用できます。

/Page2.xaml

パック URI の解決

パック URI の形式により、さまざまな種類のファイルのパック URI が同じように見えるようになります。 たとえば、次の絶対パック URI を考えてみます。

pack://application:,,,/ResourceOrContentFile.xaml

この絶対パック URI は、ローカル アセンブリ内のリソース ファイルまたはコンテンツ ファイルを参照できます。 次の相対 URI についても同じことが当てはまります。

/ResourceOrContentFile.xaml

パック URI が参照するファイルの種類を判断するために、WPF は次のヒューリスティックを使用して、ローカル アセンブリおよびコンテンツ ファイル内のリソース ファイルの URI を解決します。

  1. パック URI に一致する AssemblyAssociatedContentFileAttribute 属性のアセンブリ メタデータをプローブします。

  2. AssemblyAssociatedContentFileAttribute属性が見つかった場合、パック URI のパスはコンテンツ ファイルを参照します。

  3. AssemblyAssociatedContentFileAttribute属性が見つからない場合は、ローカル アセンブリにコンパイルされるセット リソース ファイルをプローブします。

  4. パック URI のパスと一致するリソース ファイルが見つかった場合、パック URI のパスはリソース ファイルを参照します。

  5. リソースが見つからない場合、内部で作成された Uri は無効です。

URI 解決は、次を参照する URI には適用されません。

  • 参照アセンブリ内のコンテンツ ファイル: これらのファイルの種類は WPF ではサポートされていません。

  • 参照アセンブリ内の埋め込みファイル: 参照アセンブリの名前と ;component サフィックスの両方が含まれるため、それらを識別する URI は一意です。

  • 元のサイトファイル: それらを識別するURIは、一意です。なぜなら、siteoforigin:/// の権限を含むパックURIでのみ識別可能な唯一のファイルだからです。

パック URI 解決で可能な 1 つの簡略化は、コードがリソース ファイルとコンテンツ ファイルの場所に多少依存しないためです。 たとえば、コンテンツ ファイルとして再構成されたリソース ファイルがローカル アセンブリ内にある場合、リソースのパック URI は、パック URI を使用するコードと同じままです。

パック URI を使用したプログラミング

多くの WPF クラスは、パック URI で設定できるプロパティを実装します。次に例を示します。

これらのプロパティは、マークアップとコードの両方から設定できます。 このセクションでは、両方の基本的な構成を示し、一般的なシナリオの例を示します。

マークアップでのパック URI の使用

パック URI は、パック URI を持つ属性の要素を設定することによって、マークアップで指定されます。 例えば次が挙げられます。

<element attribute="pack://application:,,,/File.xaml" />

表 1 は、マークアップで指定できるさまざまな絶対パック URI を示しています。

表 1: マークアップの絶対パック URI(ユニバーサルリソース識別子)

ファイル 絶対パックURI
リソース ファイル - ローカル アセンブリ "pack://application:,,,/ResourceFile.xaml"
サブフォルダー内のリソース ファイル - ローカル アセンブリ "pack://application:,,,/Subfolder/ResourceFile.xaml"
リソース ファイル - 参照されるアセンブリ "pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml"
参照先アセンブリのサブフォルダー内のリソース ファイル "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
バージョン管理された参照アセンブリ内のリソース ファイル "pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml"
コンテンツ ファイル "pack://application:,,,/ContentFile.xaml"
サブフォルダー内のコンテンツ ファイル "pack://application:,,,/Subfolder/ContentFile.xaml"
起源サイトファイル "pack://siteoforigin:,,,/SOOFile.xaml"
サブフォルダー内の元のサイトファイル "pack://siteoforigin:,,,/Subfolder/SOOFile.xaml"

表 2 は、マークアップで指定できるさまざまな相対パック URI を示しています。

表 2: マークアップの相対パック URI

ファイル 相対パック URI
ローカル アセンブリ内のリソース ファイル "/ResourceFile.xaml"
ローカル アセンブリのサブフォルダー内のリソース ファイル "/Subfolder/ResourceFile.xaml"
参照アセンブリ内のリソース ファイル "/ReferencedAssembly;component/ResourceFile.xaml"
参照先アセンブリのサブフォルダー内のリソース ファイル "/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
コンテンツ ファイル "/ContentFile.xaml"
サブフォルダー内のコンテンツ ファイル "/Subfolder/ContentFile.xaml"

コードでのパック URI の使用

コードでパック URI を指定するには、 Uri クラスをインスタンス化し、パラメーターとしてコンストラクターにパック URI を渡します。 これを次の例で示します。

Uri uri = new Uri("pack://application:,,,/File.xaml");

既定では、 Uri クラスはパック URI を絶対と見なします。 したがって、 Uri クラスのインスタンスが相対パック URI で作成されると、例外が発生します。

Uri uri = new Uri("/File.xaml");

幸いにも、Uri(String, UriKind) クラス コンストラクターのUriオーバーロードは、パック URI が絶対 URI か相対かを指定できるように、UriKind型のパラメーターを受け取ります。

// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml",
                        UriKind.Relative);

指定されたパック URI が 1 つ以上であることが確実な場合は、 Absolute または Relative のみを指定する必要があります。 実行時にユーザーがパック URI を入力したときなど、使用されるパック URI の種類がわからない場合は、代わりに RelativeOrAbsolute を使用します。

// Relative or Absolute URI provided by user via a text box
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);

表 3 は、 System.Uriを使用してコードで指定できるさまざまな相対パック URI を示しています。

表 3: コード内の絶対パッケージ URI

ファイル 絶対パックURI
リソース ファイル - ローカル アセンブリ Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute);
サブフォルダー内のリソース ファイル - ローカル アセンブリ Uri uri = new Uri("pack://application:,,,/Subfolder/ResourceFile.xaml", UriKind.Absolute);
リソース ファイル - 参照されるアセンブリ Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Absolute);
参照先アセンブリのサブフォルダー内のリソース ファイル Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Absolute);
バージョン管理された参照アセンブリ内のリソース ファイル Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.Absolute);
コンテンツ ファイル Uri uri = new Uri("pack://application:,,,/ContentFile.xaml", UriKind.Absolute);
サブフォルダー内のコンテンツ ファイル Uri uri = new Uri("pack://application:,,,/Subfolder/ContentFile.xaml", UriKind.Absolute);
起源サイトファイル Uri uri = new Uri("pack://siteoforigin:,,,/SOOFile.xaml", UriKind.Absolute);
サブフォルダー内の元のサイトファイル Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/SOOFile.xaml", UriKind.Absolute);

表 4 は、 System.Uriを使用してコードで指定できるさまざまな相対パック URI を示しています。

表 4: コード内の相対パック URI

ファイル 相対パック URI
リソース ファイル - ローカル アセンブリ Uri uri = new Uri("/ResourceFile.xaml", UriKind.Relative);
サブフォルダー内のリソース ファイル - ローカル アセンブリ Uri uri = new Uri("/Subfolder/ResourceFile.xaml", UriKind.Relative);
リソース ファイル - 参照されるアセンブリ Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Relative);
サブフォルダー内のリソース ファイル - 参照されるアセンブリ Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative);
コンテンツ ファイル Uri uri = new Uri("/ContentFile.xaml", UriKind.Relative);
サブフォルダー内のコンテンツ ファイル Uri uri = new Uri("/Subfolder/ContentFile.xaml", UriKind.Relative);

一般的なパック URI のシナリオ

前のセクションでは、リソース、コンテンツ、および配信元サイト のファイルを識別するためのパック URI を構築する方法について説明しました。 WPF では、これらの構造はさまざまな方法で使用され、次のセクションではいくつかの一般的な使用方法について説明します。

アプリケーションの起動時に表示する UI の指定

StartupUri は、WPF アプリケーションの起動時に表示する最初の UI を指定します。 スタンドアロン アプリケーションの場合、次の例に示すように、UI をウィンドウにすることができます。

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

スタンドアロン アプリケーションと XAML ブラウザー アプリケーション (XBAP) では、次の例に示すように、最初の UI としてページを指定することもできます。

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

アプリケーションがスタンドアロン アプリケーションであり、ページが StartupUri で指定されている場合、WPF はページをホストする NavigationWindow を開きます。 XBAP の場合、ページはホスト ブラウザーに表示されます。

次の例は、ページに移動する方法を示しています。

<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>

WPF で移動するさまざまな方法の詳細については、「 ナビゲーションの概要」を参照してください。

ウィンドウ アイコンの指定

次の例は、URI を使用してウィンドウのアイコンを指定する方法を示しています。

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.MainWindow"
    Icon="WPFIcon1.ico">
</Window>

詳細については、Iconを参照してください。

画像、オーディオ、およびビデオ ファイルの読み込み

WPF を使用すると、次の例に示すように、さまざまな種類のメディアをアプリケーションで使用できます。これらはすべて識別し、パック URI で読み込むことができます。

<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/bee.wmv" />
<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/ringin.wav" />
<Image Source="Images/Watermark.png" />

メディア コンテンツの操作の詳細については、「 グラフィックスとマルチメディア」を参照してください。

元のサイトからのリソース ディクショナリの読み込み

リソース ディクショナリ (ResourceDictionary) を使用して、アプリケーション テーマをサポートできます。 テーマを作成および管理する 1 つの方法は、アプリケーションの起点サイトにあるリソース ディクショナリとして複数のテーマを作成することです。 これにより、アプリケーションを再コンパイルして再デプロイすることなく、テーマを追加および更新できます。 これらのリソース ディクショナリは、次の例に示すように、パック URI を使用して識別して読み込むことができます。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml">
  <Application.Resources>
    <ResourceDictionary Source="pack://siteoforigin:,,,/PageTheme.xaml" />
  </Application.Resources>
</Application>

WPF のテーマの概要については、「 スタイル設定とテンプレート」を参照してください。

こちらも参照ください