Freigeben über


WPF-Anwendungsressource, -Inhalte und -Datendateien

Microsoft Windows-Anwendungen sind häufig von Dateien abhängig, die nicht ausführbare Daten enthalten, z. B. Extensible Application Markup Language (XAML), Bilder, Video und Audio. Windows Presentation Foundation (WPF) bietet spezielle Unterstützung für das Konfigurieren, Identifizieren und Verwenden dieser Arten von Datendateien, die als Anwendungsdatendateien bezeichnet werden. Diese Unterstützung dreht sich um einen bestimmten Satz von Anwendungsdatendateitypen, einschließlich:

  • Ressourcendateien: Datendateien, die in einer ausführbaren Oder Bibliotheks-WPF-Assembly kompiliert werden.

  • Inhaltsdateien: Eigenständige Datendateien, die eine explizite Zuordnung zu einer ausführbaren WPF-Assembly aufweisen.

  • Site of Origin Files: Eigenständige Datendateien, die keine Zuordnung zu einer ausführbaren WPF-Assembly haben.

Eine wichtige Unterscheidung zwischen diesen drei Dateitypen besteht darin, dass Ressourcendateien und Inhaltsdateien zur Erstellungszeit bekannt sind; eine Assembly verfügt über explizite Kenntnisse darüber. Für Ursprungsdateien kann eine Assembly jedoch überhaupt keine Kenntnisse davon haben oder nur implizites Wissen über einen URI-Verweis (Uniform Resource Identifier) des Pakets; im Falle des Letzteren gibt es keine Garantie, dass die referenzierte Ursprungsdatei tatsächlich existiert.

Um auf Anwendungsdatendateien zu verweisen, verwendet Windows Presentation Foundation (WPF) das Pack Uniform Resource Identifier (URI)-Schema, das in Den Pack-URIs in WPF ausführlich beschrieben wird.

In diesem Thema wird beschrieben, wie Anwendungsdatendateien konfiguriert und verwendet werden.

Ressourcendateien

Wenn eine Anwendungsdatendatei immer für eine Anwendung verfügbar sein muss, besteht die einzige Möglichkeit, die Verfügbarkeit zu gewährleisten, darin besteht, sie in der Haupt-ausführbaren Assembly einer Anwendung oder einer seiner referenzierten Assemblys zu kompilieren. Dieser Typ von Anwendungsdatendatei wird als Ressourcendatei bezeichnet.

Sie sollten Ressourcendateien verwenden, wenn:

  • Sie müssen den Inhalt der Ressourcendatei nicht aktualisieren, nachdem sie in eine Assembly kompiliert wurde.

  • Sie möchten die Komplexität der Anwendungsverteilung vereinfachen, indem Sie die Anzahl der Dateiabhängigkeiten verringern.

  • Ihre Anwendungsdatendatei muss lokalisierbar sein (siehe WPF Globalization and Localization Overview).

Hinweis

Die in diesem Abschnitt beschriebenen Ressourcendateien unterscheiden sich von den in XAML-Ressourcen beschriebenen Ressourcendateien und unterscheiden sich von den eingebetteten oder verknüpften Ressourcen, die in "Anwendungsressourcen verwalten(.NET)" beschrieben werden.

Konfigurieren von Ressourcendateien

In WPF ist eine Ressourcendatei eine Datei, die in einem MsBuild-Projekt (Microsoft Build Engine) als Resource Element enthalten ist.

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

Hinweis

In Visual Studio erstellen Sie eine Ressourcendatei, indem Sie einem Projekt eine Datei hinzufügen und deren Build Action auf Resource setzen.

Wenn das Projekt erstellt wird, kompiliert MSBuild die Ressource in der Assembly.

Verwenden von Ressourcendateien

Zum Laden einer Ressourcendatei können Sie die GetResourceStream Methode der Application Klasse aufrufen und einen Pack-URI übergeben, der die gewünschte Ressourcendatei identifiziert. GetResourceStream gibt ein StreamResourceInfo Objekt zurück, das die Ressourcendatei als eine Stream verfügbar macht und den Inhaltstyp beschreibt.

Der folgende Code zeigt, wie Sie GetResourceStream verwenden, um eine Page-Ressourcendatei zu laden und sie als Inhalt einer Frame (pageFrame) festzulegen.

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

Beim Aufrufen von GetResourceStream erhalten Sie Zugriff auf Stream, müssen jedoch zusätzliche Schritte ausführen, um es in den Typ der Eigenschaft zu konvertieren, mit der Sie es festlegen. Stattdessen können Sie WPF das Öffnen und Konvertieren von Stream überlassen, indem Sie eine Ressourcendatei direkt in die Eigenschaft eines Typs mit Code laden.

Das folgende Beispiel zeigt, wie Sie eine Page direkt in einen Frame (pageFrame) mithilfe von Code laden.

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

Das folgende Beispiel ist das Markupäquivalent des vorherigen Beispiels.

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

Anwendungscodedateien als Ressourcendateien

Auf eine spezielle Gruppe von WPF-Anwendungscodedateien kann mithilfe von Paket-URIs verwiesen werden, einschließlich Fenstern, Seiten, Flussdokumenten und Ressourcenwörterbüchern. Sie können beispielsweise die Application.StartupUri Eigenschaft mit einem Pack-URI festlegen, der auf das Fenster oder die Seite verweist, das sie laden möchten, wenn eine Anwendung gestartet wird.

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

Sie können dies tun, wenn eine XAML-Datei in einem MSBuild-Projekt als Page Element enthalten ist.

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

Hinweis

In Visual Studio fügen Sie ein neues Window, , NavigationWindow, Page, , FlowDocumentoder ResourceDictionary einem Projekt hinzu, die Build Action für die Markupdatei standardmäßig Page.

Wenn ein Projekt mit Page Elementen kompiliert wird, werden die XAML-Elemente in das Binärformat konvertiert und in die zugeordnete Assembly kompiliert. Daher können diese Dateien auf die gleiche Weise wie typische Ressourcendateien verwendet werden.

Hinweis

Wenn eine XAML-Datei als Resource Element konfiguriert ist und keine CodeBehind-Datei enthält, wird der rohe XAML-Code in eine Assembly kompiliert, anstatt in einer binären Version des rohen XAML.

Inhaltsdateien

Eine Inhaltsdatei wird zusammen mit einer ausführbaren Assembly als lose Datei verteilt. Obwohl sie nicht in einer Assembly kompiliert werden, werden Assemblys mit Metadaten kompiliert, die eine Zuordnung zu jeder Inhaltsdatei herstellen.

Sie sollten Inhaltsdateien verwenden, wenn Ihre Anwendung eine bestimmte Gruppe von Anwendungsdatendateien erfordert, die Sie aktualisieren möchten, ohne die Assembly neu zu kompilieren, die sie verwendet.

Konfigurieren von Inhaltsdateien

Um einem Projekt eine Inhaltsdatei hinzuzufügen, muss eine Anwendungsdatendatei als Content Element eingeschlossen werden. Da eine Inhaltsdatei nicht direkt in die Assembly kompiliert wird, müssen Sie das MSBuild-Metadatenelement CopyToOutputDirectory festlegen, um anzugeben, dass die Inhaltsdatei an einen Speicherort kopiert wird, der relativ zur integrierten Assembly ist. Wenn die Ressource jedes Mal, wenn ein Projekt erstellt wird, in den Buildausgabeordner kopiert werden soll, legen Sie das CopyToOutputDirectory Metadatenelement mit dem Always Wert fest. Andernfalls können Sie sicherstellen, dass nur die neueste Version der Ressource mithilfe PreserveNewest des Werts in den Buildausgabeordner kopiert wird.

Im Folgenden finden Sie eine Datei, die als Inhaltsdatei konfiguriert ist, die nur dann in den Buildausgabeordner kopiert wird, wenn dem Projekt eine neue Version der Ressource hinzugefügt wird.

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

Hinweis

In Visual Studio erstellen Sie eine Inhaltsdatei, indem Sie eine Datei zu einem Projekt hinzufügen und deren Wert Build Action auf Content festlegen sowie Copy to Output Directory auf Copy always (identisch mit Always) und Copy if newer (wie PreserveNewest).

Wenn das Projekt erstellt wird, wird ein AssemblyAssociatedContentFileAttribute Attribut in die Metadaten der Assembly für jede Inhaltsdatei kompiliert.

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

Der Wert des Elements AssemblyAssociatedContentFileAttribute impliziert den Pfad zur Inhaltsdatei relativ zu seiner Position im Projekt. Wenn sich beispielsweise eine Inhaltsdatei in einem Projektunterordner befindet, werden die zusätzlichen Pfadinformationen in den AssemblyAssociatedContentFileAttribute Wert integriert.

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

Der AssemblyAssociatedContentFileAttribute Wert ist auch der Wert des Pfads zur Inhaltsdatei im Buildausgabeordner.

Verwenden von Inhaltsdateien

Zum Laden einer Inhaltsdatei können Sie die GetContentStream Methode der Application Klasse aufrufen und einen Pack-URI übergeben, der die gewünschte Inhaltsdatei identifiziert. GetContentStream gibt ein StreamResourceInfo Objekt zurück, das die Inhaltsdatei als inhaltstyp Stream verfügbar macht und beschreibt.

Im folgenden Code wird beispielsweise gezeigt, wie GetContentStream eine Page Inhaltsdatei geladen und als Inhalt eines Frame (pageFrame) festgelegt wird.

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

Beim Aufrufen von GetContentStream erhalten Sie Zugriff auf Stream, müssen jedoch zusätzliche Schritte ausführen, um es in den Typ der Eigenschaft zu konvertieren, mit der Sie es festlegen. Stattdessen können Sie WPF das Öffnen und Konvertieren von Stream überlassen, indem Sie eine Ressourcendatei direkt in die Eigenschaft eines Typs mit Code laden.

Das folgende Beispiel zeigt, wie Sie eine Page direkt in einen Frame (pageFrame) mithilfe von Code laden.

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

Das folgende Beispiel ist das Markupäquivalent des vorherigen Beispiels.

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

Website der Ursprungsdateien

Ressourcendateien haben eine explizite Beziehung zu den Assemblies, mit denen sie zusammen verteilt werden, gemäß der Definition durch AssemblyAssociatedContentFileAttribute. Es gibt jedoch Situationen, in denen Sie entweder eine implizite oder nicht vorhandene Beziehung zwischen einer Assembly und einer Anwendungsdatendatei einrichten möchten, einschließlich der folgenden Situationen:

  • Zur Kompilierungszeit ist keine Datei vorhanden.

  • Sie wissen nicht, welche Dateien Ihre Assembly bis zur Laufzeit benötigt.

  • Sie möchten Dateien aktualisieren können, ohne die Assembly neu zu kompilieren, der sie zugeordnet sind.

  • Ihre Anwendung verwendet große Datendateien, z. B. Audio und Video, und Sie möchten, dass Benutzer sie nur herunterladen, wenn sie sich dafür entscheiden.

Es ist möglich, diese Dateitypen mithilfe herkömmlicher URI-Schemas wie z. B. dem file:///-Schema und dem http://-Schema zu laden.

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

Die file:/// und http:// Schema erfordern jedoch, dass Ihre Anwendung volle Vertrauenswürdigkeit besitzt. Wenn Es sich bei Ihrer Anwendung um eine XAML-Browseranwendung (XBAP) handelt, die über das Internet oder Intranet gestartet wurde und nur den Satz von Berechtigungen anfordert, die für Anwendungen, die von diesen Speicherorten gestartet werden dürfen, können lose Dateien nur von der Ursprungswebsite der Anwendung (Startspeicherort) geladen werden. Solche Dateien werden als Ursprungsort-Dateien bezeichnet.

Die Website von Ursprungsdateien ist die einzige Option für teilweise vertrauenswürdige Anwendungen, obwohl sie nicht auf teilweise vertrauenswürdige Anwendungen beschränkt sind. Voll vertrauenswürdige Anwendungen müssen möglicherweise weiterhin Anwendungsdatendateien laden, die sie zur Erstellungszeit nicht kennen. während Voll vertrauenswürdige Anwendungen file:/// verwenden können, ist es wahrscheinlich, dass die Anwendungsdatendateien im selben Ordner wie ein Unterordner der Anwendungsassembly installiert werden. In diesem Fall ist die Verwendung von "Site of Origin"-Verweisen einfacher als die Verwendung von file:///, da die Verwendung von file:/// erfordert, dass Sie den vollständigen Pfad der Datei ausarbeiten müssen.

Hinweis

Ursprungsdateien werden nicht mit einer XAML-Browseranwendung (XBAP) auf einem Clientcomputer zwischengespeichert, während Inhaltsdateien zwischengespeichert werden. Folglich werden sie nur heruntergeladen, wenn sie ausdrücklich angefordert werden. Wenn eine XAML-Browseranwendung (XBAP)-Anwendung über große Mediendateien verfügt, bedeutet die Konfiguration als Website von Ursprungsdateien, dass der anfängliche Anwendungsstart viel schneller ist und die Dateien nur bei Bedarf heruntergeladen werden.

Konfigurieren von Site of Origin-Dateien

Wenn Ihre Website der Ursprungsdateien zur Kompilierungszeit nicht vorhanden oder unbekannt ist, müssen Sie herkömmliche Bereitstellungsmechanismen verwenden, um sicherzustellen, dass die erforderlichen Dateien zur Laufzeit verfügbar sind, einschließlich der Verwendung des XCopy Befehlszeilenprogramms oder des Microsoft Windows Installer.

Wenn Sie bereits während der Kompilierung wissen, welche Dateien sich am Ursprungsstandort befinden sollen, aber dennoch eine explizite Abhängigkeit vermeiden möchten, können Sie diese Dateien einem MSBuild-Projekt als None Elemente hinzufügen. Wie bei Inhaltsdateien müssen Sie das MSBuild-Attribut CopyToOutputDirectory festlegen, um anzugeben, dass die Ursprungsstandortdatei an einen Speicherort kopiert wird, der relativ zur erstellten Assembly ist, indem Sie den Wert entweder für Always oder PreserveNewest angeben.

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

Hinweis

In Visual Studio erstellen Sie eine Ursprungsdatei, indem Sie eine Datei zu einem Projekt hinzufügen und ihre Einstellung auf Build Action setzen.

Wenn das Projekt erstellt wird, kopiert MSBuild die angegebenen Dateien in den Buildausgabeordner.

Verwenden von Ursprungsort-Dateien

Um eine Website der Ursprungsdatei zu laden, können Sie die GetRemoteStream Methode der Application Klasse aufrufen und einen Pack-URI übergeben, der die gewünschte Ursprungswebsite identifiziert. GetRemoteStream gibt ein StreamResourceInfo Objekt zurück, das die Website der Ursprungsdatei als eine Stream verfügbar macht und den Inhaltstyp beschreibt.

Im folgenden Code wird beispielsweise gezeigt, wie GetRemoteStream verwendet wird, um eine Page Ursprungsdatei zu laden und sie als Inhalt von Frame (pageFrame) festzulegen.

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

Beim Aufrufen von GetRemoteStream erhalten Sie Zugriff auf Stream, müssen jedoch zusätzliche Schritte ausführen, um es in den Typ der Eigenschaft zu konvertieren, mit der Sie es festlegen. Stattdessen können Sie WPF das Öffnen und Konvertieren von Stream überlassen, indem Sie eine Ressourcendatei direkt in die Eigenschaft eines Typs mit Code laden.

Das folgende Beispiel zeigt, wie Sie eine Page direkt in einen Frame (pageFrame) mithilfe von Code laden.

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

Das folgende Beispiel ist das Markupäquivalent des vorherigen Beispiels.

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

Neuerstellung nach dem Ändern des Buildtyps

Nachdem Sie den Buildtyp einer Anwendungsdatendatei geändert haben, müssen Sie die gesamte Anwendung neu erstellen, um sicherzustellen, dass diese Änderungen angewendet werden. Wenn Sie nur die Anwendung erstellen, werden die Änderungen nicht angewendet.

Siehe auch