マージされたリソース ディクショナリ

マージされたリソース ディクショナリ機能が、Windows Presentation Foundation (WPF) リソースによってサポートされています。 この機能を使用すると、コンパイル済み XAML アプリケーションの外部で、WPF アプリケーションのリソース部分を定義できます。 その後、リソースをアプリケーション間で共有できます。また、ローカライズ用に簡単に切り分けることができます。

マージされたリソース ディクショナリの導入

マークアップでは、マージされたリソース ディクショナリをページに導入するために次の構文を使います。

<Page.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="myresourcedictionary.xaml"/>
      <ResourceDictionary Source="myresourcedictionary2.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Page.Resources>

ResourceDictionary 要素には x:Key Directive がないことに注意してください。通常、これはリソース コレクション内のすべての項目に必要です。 ただし、MergedDictionaries コレクション内にもう 1 つの ResourceDictionary 参照があることは特殊なケースであり、このマージされたリソース ディクショナリのシナリオのために予約されています。 マージされたリソース ディクショナリを導入する ResourceDictionaryx:Key Directive を含めることはできません。 通常、MergedDictionaries コレクション内の各 ResourceDictionary には Source 属性を指定します。 Source の値は、マージされるリソース ファイルの場所に解決される Uniform Resource Identifier (URI) である必要があります。 その URI の宛先は、ルート要素が ResourceDictionary である別の XAML ファイルである必要があります。

注意

Source を指定する代わりに、または指定したソースから含めるリソースに加えて、マージされたディクショナリとして指定された ResourceDictionary 内にリソースを定義することはできます。 ただし、これは一般的なシナリオではありません。マージされたディクショナリの主要なシナリオは、外部ファイルの場所からリソースをマージすることです。 ページのマークアップ内でリソースを指定する場合は、通常、マージされたディクショナリではなくメインの ResourceDictionary で定義する必要があります。

マージされたディクショナリの動作

マージされたディクショナリ内のリソースは、それらのリソースがマージされる先のメイン リソース ディクショナリのスコープの直後のリソース参照スコープの場所全体を占めます。 リソース キーは個々のディクショナリ内で一意である必要がありますが、マージされたディクショナリのセット内に 1 つのキーが複数回存在してもかまいません。 この場合、返されるリソースは、MergedDictionaries コレクション内で順番に見つかった最後のディクショナリから取得されます。 MergedDictionaries コレクションが XAML で定義されている場合、コレクション内のマージされたディクショナリの順序は、マークアップで指定されている要素の順序になります。 プライマリ ディクショナリ内とマージされたディクショナリ内の両方でキーが定義されている場合、返されるリソースはプライマリ ディクショナリから取られます。 これらのスコープ規則は、静的なリソース参照と動的なリソース参照の両方に等しく適用されます。

マージされたディクショナリとコード

マージされたディクショナリは、コードを使って Resources ディクショナリに追加できます。 すべての Resources プロパティに存在し、既定で初期値は空である ResourceDictionary にも、既定で初期値は空である MergedDictionaries コレクション プロパティがあります。 コードを使用してマージされたディクショナリを追加するには、目的のプライマリ ResourceDictionary への参照を取得し、その MergedDictionaries プロパティ値を取得し、MergedDictionaries に含まれるジェネリック Collection に対して Add を呼び出します。 追加するオブジェクトは、新しい ResourceDictionary である必要があります。 コード内では、Source プロパティを設定しません。 そうではなく、作成するか読み込むことで、ResourceDictionary オブジェクトを取得する必要があります。 既存の ResourceDictionary を読み込み、ResourceDictionary ルートを持つ既存の XAML ファイル ストリームに対して XamlReader.Load を呼び出し、XamlReader.Load 戻り値を ResourceDictionary にキャストするという方法もあります。

マージされたリソース ディクショナリの URI

マージされたリソース ディクショナリを含める方法にはいくつかの手法があります。これは、使用する Uniform Resource Identifier (URI) 形式で示されます。 大まかに言えば、これらの手法は 2 つのカテゴリに分類できます。プロジェクトの一部としてコンパイルされるリソースと、プロジェクトの一部としてコンパイルされないリソースです。

プロジェクトの一部としてコンパイルされるリソースの場合は、リソースの場所を参照する相対パスを使うことができます。 相対パスは、コンパイル中に評価されます。 リソースは、リソースのビルド アクションでプロジェクトの一部として定義する必要があります。 リソースの .xaml ファイルをリソースとしてプロジェクトに組み込む場合は、リソース ファイルを出力ディレクトリにコピーする必要がありません。リソースは、コンパイルされたアプリケーション内にあらかじめ組み込まれます。 コンテンツのビルド アクションを使うこともできますが、その場合は、ファイルを出力ディレクトリにコピーして、実行可能ファイルに対して同じパスにリソース ファイルを配置する必要があります。

注意

埋め込みリソースのビルド アクションは使用しないでください。 WPF アプリケーションのビルド アクション自体はサポートされていますが、Source の解決には ResourceManager が組み込まれていないため、個々のリソースをストリームから分離できません。 ResourceManager を使用してリソースにアクセスしている限り、埋め込みリソースを他の目的に使用することもできます。

これと関連して、XAML ファイルに対するパック URI を使い、それをソースとして参照する手法もあります。 パック URI を使用すると、参照したアセンブリのコンポーネントを参照したり、その他の手法を利用したりできます。 パック URI の詳細については、「WPF アプリケーションのリソース ファイル、コンテンツ ファイル、およびデータ ファイル」を参照してください。

プロジェクトの一部としてコンパイルされないリソースでは、URI が実行時に評価されます。 リソース ファイルを参照するために、file: や http: などの一般的な URI トランスポートを使うことができます。 コンパイルされないリソースの手法を使うことの欠点は、file: アクセスには追加の配置手順が必要になることと、http: アクセスはインターネット セキュリティ ゾーンを意味することです。

マージされたディクショナリの再利用

マージするリソース ディクショナリは、すべての有効な Uniform Resource Identifier (URI) を使って参照できるため、マージされたリソース ディクショナリをアプリケーション間で再利用または共有することができます。 これを行うための具体的な方法は、アプリケーションの配置方法と、採用するアプリケーション モデルによって異なります。 前述のパック URI の手法を使うと、開発中にアセンブリ参照を共有することにより、マージされたリソースを複数のプロジェクトから取得する一般的な方法を利用することができます。 このシナリオでは、リソースはまだクライアントによって配布されるため、少なくとも 1 つのアプリケーションで参照先のアセンブリを配置する必要があります。 また、http プロトコルを使う分散 URI によって、マージされたリソースを参照することもできます。

マージされたディクショナリ/アプリケーションの配置で考えられる別のシナリオは、マージされたディクショナリをローカル アプリケーション ファイルとして、またはローカルの共有記憶域に書き出すことです。

ローカリゼーション

ローカライズする必要のあるリソースが、プライマリ ディクショナリにマージされたディクショナリに分離されて、Loose XAML ファイルとして保持されている場合、これらのファイルを別個にローカライズすることができます。 これは、サテライト リソース アセンブリをローカライズするよりも簡易な手法です。 詳細については、「WPF のグローバリゼーションおよびローカリゼーションの概要」を参照してください。

関連項目