次の方法で共有


WPF アプリケーション リソース、コンテンツ、およびデータ ファイル

Microsoft Windows アプリケーションは、多くの場合、拡張可能なアプリケーション マークアップ言語 (XAML)、イメージ、ビデオ、オーディオなど、実行可能でないデータを含むファイルに依存します。 Windows Presentation Foundation (WPF) では、アプリケーション データ ファイルと呼ばれるこれらの種類のデータ ファイルを構成、識別、および使用するための特別なサポートが提供されます。 このサポートは、次のような特定のアプリケーション データ ファイルの種類を中心に展開されます。

  • リソース ファイル: 実行可能ファイルまたはライブラリ WPF アセンブリにコンパイルされるデータ ファイル。

  • コンテンツ ファイル: 実行可能な WPF アセンブリとの明示的な関連付けを持つスタンドアロン データ ファイル。

  • 元のサイト ファイル: 実行可能な WPF アセンブリと関連付けのないスタンドアロン データ ファイル。

これら 3 種類のファイルの間で行う重要な違いの 1 つは、リソース ファイルとコンテンツ ファイルがビルド時に認識されていることです。アセンブリには、それらの明示的な知識があります。 ただし、元のサイト ファイルの場合、アセンブリにはそれらの知識がまったくない場合や、パックの UNIFORM Resource Identifier (URI) 参照を介した暗黙的な知識が含まれる場合があります。後者の場合、参照元サイトファイルが実際に存在するという保証はありません。

Windows Presentation Foundation (WPF) は、アプリケーション データ ファイルを参照するために、WPF のパック URI で詳しく説明されている Pack Uniform Resource Identifier (URI) スキームを使用します。

このトピックでは、アプリケーション データ ファイルを構成して使用する方法について説明します。

リソース ファイル

アプリケーション データ ファイルを常にアプリケーションで使用できる必要がある場合、可用性を保証する唯一の方法は、アプリケーションのメイン実行可能アセンブリまたはその参照されるアセンブリのいずれかにコンパイルすることです。 この種類のアプリケーション データ ファイルは、 リソース ファイルと呼ばれます。

リソース ファイルは、次の場合に使用する必要があります。

  • リソース ファイルがアセンブリにコンパイルされた後で、リソース ファイルの内容を更新する必要はありません。

  • ファイルの依存関係の数を減らすことで、アプリケーションの配布の複雑さを簡略化する必要があります。

  • アプリケーション データ ファイルはローカライズ可能である必要があります ( 「WPF のグローバリゼーションとローカリゼーションの概要」を参照してください)。

このセクションで説明するリソース ファイルは、 XAML リソース で説明されているリソース ファイルとは異なり、「アプリケーション リソースの 管理 (.NET)」で説明されている埋め込みリソースまたはリンクされたリソースとは異なります。

リソース ファイルの構成

WPF では、リソース ファイルは、Microsoft ビルド エンジン (MSBuild) プロジェクトに Resource 項目として含まれるファイルです。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Resource Include="ResourceFile.xaml" />
  </ItemGroup>
  ...
</Project>

Visual Studio でリソース ファイルを作成するには、プロジェクトにファイルを追加し、その Build ActionResource に設定します。

プロジェクトがビルドされると、MSBuild によってリソースがアセンブリにコンパイルされます。

リソース ファイルの使用

リソース ファイルを読み込むには、GetResourceStream クラスのApplication メソッドを呼び出し、目的のリソース ファイルを識別するパック URI を渡します。 GetResourceStreamは、リソース ファイルをStreamResourceInfoとして公開し、そのコンテンツ タイプを記述するStream オブジェクトを返します。

例として、次のコードは、 GetResourceStream を使用して Page リソース ファイルを読み込み、 Frame のコンテンツとして設定する方法を示しています (pageFrame)。

// Navigate to xaml page
Uri uri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetResourceStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

GetResourceStreamを呼び出すとStreamにアクセスできますが、それを設定するプロパティの型に変換する追加の作業を実行する必要があります。 代わりに、コードを使用してリソース ファイルを型のプロパティに直接読み込むことで、WPF が Stream を開いて変換できるようにすることができます。

次の例は、コードを使用して PageFrame (pageFrame) に直接読み込む方法を示しています。

Uri pageUri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri

次の例は、前の例と同等のマークアップです。

<Frame Name="pageFrame" Source="PageResourceFile.xaml" />

リソース ファイルとしてのアプリケーション コード ファイル

WPF アプリケーション コード ファイルの特別なセットは、ウィンドウ、ページ、フロー ドキュメント、リソース ディクショナリなどのパック URI を使用して参照できます。 たとえば、アプリケーションの起動時に読み込むウィンドウまたはページを参照するパック URI を使用して、 Application.StartupUri プロパティを設定できます。

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

これは、XAML ファイルが MSBuild プロジェクトに Page 項目として含まれている場合に実行できます。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Page Include="MainWindow.xaml" />
  </ItemGroup>
  ...
</Project>

Visual Studio では、新しい WindowNavigationWindowPageFlowDocument、または ResourceDictionary をプロジェクトに追加すると、マークアップ ファイルの Build Action は既定で Pageされます。

Page項目を含むプロジェクトがコンパイルされると、XAML 項目はバイナリ形式に変換され、関連付けられたアセンブリにコンパイルされます。 そのため、これらのファイルは、一般的なリソース ファイルと同じ方法で使用できます。

XAML ファイルが Resource 項目として構成されていて、分離コード ファイルがない場合、生の XAML は生の XAML のバイナリ バージョンではなくアセンブリにコンパイルされます。

コンテンツ ファイル

コンテンツ ファイルは、実行可能アセンブリと共にルーズ ファイルとして配布されます。 アセンブリにはコンパイルされませんが、アセンブリは、各コンテンツ ファイルとの関連付けを確立するメタデータを使用してコンパイルされます。

コンテンツ ファイルは、アプリケーションで使用するアセンブリを再コンパイルせずに更新できる特定のアプリケーション データ ファイルのセットが必要な場合に使用する必要があります。

コンテンツ ファイルの構成

プロジェクトにコンテンツ ファイルを追加するには、アプリケーション データ ファイルを Content 項目として含める必要があります。 さらに、コンテンツ ファイルはアセンブリに直接コンパイルされないため、MSBuild CopyToOutputDirectory メタデータ要素を設定して、ビルドされたアセンブリを基準とする場所にコンテンツ ファイルをコピーするように指定する必要があります。 プロジェクトがビルドされるたびにリソースをビルド出力フォルダーにコピーする場合は、CopyToOutputDirectory値を使用してAlwaysメタデータ要素を設定します。 それ以外の場合は、 PreserveNewest 値を使用して、リソースの最新バージョンのみがビルド出力フォルダーにコピーされるようにすることができます。

次に示すのは、新しいバージョンのリソースがプロジェクトに追加された場合にのみビルド出力フォルダーにコピーされるコンテンツ ファイルとして構成されたファイルです。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <ItemGroup>
    <Content Include="ContentFile.xaml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  ...
</Project>

Visual Studio では、プロジェクトにファイルを追加し、その Build ActionContentに設定してコンテンツ ファイルを作成し、その Copy to Output DirectoryCopy always ( Alwaysと同じ) と Copy if newer ( PreserveNewestと同じ) に設定します。

プロジェクトがビルドされると、 AssemblyAssociatedContentFileAttribute 属性が各コンテンツ ファイルのアセンブリのメタデータにコンパイルされます。

[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]

AssemblyAssociatedContentFileAttributeの値は、プロジェクト内の位置を基準としたコンテンツ ファイルへのパスを意味します。 たとえば、コンテンツ ファイルがプロジェクト サブフォルダーにある場合、追加のパス情報は AssemblyAssociatedContentFileAttribute 値に組み込まれます。

[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]

AssemblyAssociatedContentFileAttribute値は、ビルド出力フォルダー内のコンテンツ ファイルへのパスの値でもあります。

コンテンツ ファイルの使用

コンテンツ ファイルを読み込むには、GetContentStream クラスのApplication メソッドを呼び出し、目的のコンテンツ ファイルを識別するパック URI を渡します。 GetContentStreamは、コンテンツ ファイルをStreamResourceInfoとして公開し、そのコンテンツ タイプを記述するStream オブジェクトを返します。

例として、次のコードは、 GetContentStream を使用して Page コンテンツ ファイルを読み込み、 Frame (pageFrame) のコンテンツとして設定する方法を示しています。

// Navigate to xaml page
Uri uri = new Uri("/PageContentFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetContentStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

GetContentStreamを呼び出すとStreamにアクセスできますが、それを設定するプロパティの型に変換する追加の作業を実行する必要があります。 代わりに、コードを使用してリソース ファイルを型のプロパティに直接読み込むことで、WPF が Stream を開いて変換できるようにすることができます。

次の例は、コードを使用して PageFrame (pageFrame) に直接読み込む方法を示しています。

Uri pageUri = new Uri("/PageContentFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri

次の例は、前の例と同等のマークアップです。

<Frame Name="pageFrame" Source="PageContentFile.xaml" />

発信元サイト ファイル

リソース ファイルは、 AssemblyAssociatedContentFileAttributeで定義されているアセンブリと明示的な関係を持ち、同時に配布されます。 ただし、アセンブリとアプリケーション データ ファイルの間に暗黙的なリレーションシップまたは存在しないリレーションシップを確立する必要がある場合があります。次のような場合があります。

  • コンパイル時にファイルが存在しません。

  • アセンブリに必要なファイルは、実行時までわかりません。

  • 関連付けられているアセンブリを再コンパイルせずにファイルを更新できるようにする必要があります。

  • アプリケーションでは、オーディオやビデオなどの大きなデータ ファイルが使用され、ユーザーがダウンロードする必要があるのはユーザーが選択した場合のみです。

file:///http://スキームなどの従来の URI スキームを使用して、これらの種類のファイルを読み込むことができます。

<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />

ただし、 file:///http:// スキームでは、アプリケーションに完全な信頼が必要です。 アプリケーションが、インターネットまたはイントラネットから起動された XAML ブラウザー アプリケーション (XBAP) であり、それらの場所から起動されたアプリケーションに対して許可されているアクセス許可のセットのみを要求する場合、ルース ファイルは、アプリケーションの起点サイト (起動場所) からのみ読み込むことができます。 このようなファイルは、 元のサイト ファイルと呼ばれます。

部分信頼アプリケーションに限定されるわけではありませんが、元のサイト ファイルは部分信頼アプリケーションの唯一のオプションです。 完全信頼アプリケーションでは、ビルド時に知らないアプリケーション データ ファイルを読み込む必要がある場合があります。完全信頼アプリケーションでは file:/// を使用できますが、アプリケーション のデータ ファイルは、アプリケーション アセンブリと同じフォルダーまたはサブフォルダーにインストールされる可能性があります。 この場合、file:/// を使用するにはファイルの完全なパスを処理する必要があるため、file:/// を使用するよりも、元のサイト参照を使用する方が簡単です。

元のサイト ファイルは、クライアント コンピューター上の XAML ブラウザー アプリケーション (XBAP) ではキャッシュされませんが、コンテンツ ファイルはキャッシュされます。 したがって、これらは特に要求されたときにのみダウンロードされます。 XAML ブラウザー アプリケーション (XBAP) アプリケーションに大きなメディア ファイルがある場合、元のサイト ファイルとして構成すると、アプリケーションの初回起動がはるかに高速になり、ファイルはオンデマンドでのみダウンロードされます。

起源サイトファイルの設定

元のサイトファイルがコンパイル時に存在しないか不明である場合は、 XCopy コマンドライン プログラムや Microsoft Windows インストーラーを使用するなど、実行時に必要なファイルを確実に使用できるようにするための従来の展開メカニズムを使用する必要があります。

コンパイル時に、元のサイトに配置したいファイルがわかっていても、明示的な依存関係を回避したい場合は、それらのファイルを MSBuild プロジェクトに None 項目として追加できます。 コンテンツ ファイルと同様に、MSBuild CopyToOutputDirectory 属性を設定して、 Always 値または PreserveNewest 値を指定して、ビルドされたアセンブリを基準とする場所に起点サイト ファイルをコピーするように指定する必要があります。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >
  ...
  <None Include="PageSiteOfOriginFile.xaml">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
  ...
</Project>

Visual Studio では、プロジェクトにファイルを追加し、その Build ActionNone に設定することで、元のサイト ファイルを作成します。

プロジェクトがビルドされると、MSBuild は指定されたファイルをビルド出力フォルダーにコピーします。

元のサイトにあるファイルを使用する

起点サイト ファイルを読み込むには、GetRemoteStream クラスのApplication メソッドを呼び出し、目的の起点サイト ファイルを識別するパック URI を渡します。 GetRemoteStreamStreamResourceInfo オブジェクトを返します。このオブジェクトは、元のサイト ファイルを Stream として公開し、そのコンテンツ タイプを記述します。

例として、次のコードは、 GetRemoteStream を使用して、 Page の起点サイト ファイルを読み込み、 Frame (pageFrame) のコンテンツとして設定する方法を示しています。

// Navigate to xaml page
Uri uri = new Uri("/SiteOfOriginFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetRemoteStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
' Navigate to xaml page
Dim uri As New Uri("/SiteOfOriginFile.xaml", UriKind.Relative)
Dim info As StreamResourceInfo = Application.GetRemoteStream(uri)
Dim reader As New System.Windows.Markup.XamlReader()
Dim page As Page = CType(reader.LoadAsync(info.Stream), Page)
Me.pageFrame.Content = page

GetRemoteStreamを呼び出すとStreamにアクセスできますが、それを設定するプロパティの型に変換する追加の作業を実行する必要があります。 代わりに、コードを使用してリソース ファイルを型のプロパティに直接読み込むことで、WPF が Stream を開いて変換できるようにすることができます。

次の例は、コードを使用して PageFrame (pageFrame) に直接読み込む方法を示しています。

Uri pageUri = new Uri("pack://siteoforigin:,,,/SiteOfOriginFile.xaml", UriKind.Absolute);
this.pageFrame.Source = pageUri;
Dim pageUri As New Uri("pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml", UriKind.Absolute)
Me.pageFrame.Source = pageUri

次の例は、前の例と同等のマークアップです。

<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />

ビルドの種類を変更した後の再構築

アプリケーション データ ファイルのビルドの種類を変更した後、アプリケーション全体をリビルドして、それらの変更が確実に適用されるようにする必要があります。 アプリケーションをビルドするだけの場合、変更は適用されません。

こちらも参照ください