WPF-Anwendungsressource, Inhalts- und Datendateien
Microsoft Windows-Anwendungen hängen oftmals von Dateien ab, 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 zum Konfigurieren, Identifizieren und Verwenden dieser Datendateitypen, die als Anwendungsdatendateien bezeichnet werden. Diese Unterstützung bezieht sich auf einen bestimmten Satz von Anwendungsdatendateitypen, einschließlich:
Ressourcendateien: Datendateien, die entweder in eine ausführbare oder in eine WPF-Bibliotheksassembly kompiliert werden.
Inhaltsdateien: Eigenständige Datendateien, die einer ausführbaren WPF-Assembly explizit zugeordnet sind.
Dateien der Ursprungssite: Eigenständige Datendateien, die keiner ausführbaren WPF-Assembly zugeordnet sind.
Ein wichtiger Unterschied zwischen diesen drei Dateitypen besteht darin, dass die Ressourcen- und Inhaltsdateien zur Buildzeit bekannt sind. Sie sind einer Assembly explizit bekannt. Dateien der Ursprungssite sind einer Assembly u. U. überhaupt nicht oder lediglich implizit über den Verweis auf einen Paket-uniform resource identifier (URI) bekannt. Im letzteren Fall kann nicht garantiert werden, dass die Datei der Ursprungssite, auf die verwiesen wurde, tatsächlich vorhanden ist.
Wenn Sie auf Anwendungsdatendateien verweisen möchten, verwendet Windows Presentation Foundation (WPF) das Paket-uniform resource identifier (URI)-Schema, das unter Paket-URI in WPF ausführlich beschrieben wird.
In diesem Thema wird beschrieben, wie Sie Anwendungsdatendateien konfigurieren und verwenden.
Dieses Thema enthält folgende Abschnitte.
- Ressourcendateien
- Inhaltsdateien
- Dateien der Ursprungssite
- Neuerstellung nach Ändern des Buildtyps
- Verwandte Abschnitte
Ressourcendateien
Wenn eine Anwendungsdatendatei einer Anwendung stets zur Verfügung stehen muss, kann die Verfügbarkeit nur dadurch gewährleistet werden, dass die Datei in eine der ausführbaren Hauptassemblys einer Anwendung oder in eine der Assemblys kompiliert wird, auf die verwiesen wird. Dieser Typ von Anwendungsdatendatei wird als Ressourcendatei bezeichnet.
Verwenden Sie die Ressourcendateien in folgenden Fällen:
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 von Dateiabhängigkeiten verringern.
Die Anwendungsdatendatei muss lokalisierbar sein (siehe Übersicht über WPF-Globalisierung und -Lokalisierung).
Hinweis |
---|
Ressourcenwörterbücher (XAML-Dateien mit ResourceDictionary als Element der obersten Ebene) sind keine WPF-Ressourcendateien; während WPF-Ressourcendateien Ressourcenwörterbücher sein können, gilt das umgekehrt nicht unbedingt (siehe ResourceDictionary). Darüber hinaus sind WPF-Ressourcendateien nicht identisch mit eingebetteten oder verknüpften Ressourcentypen, die mithilfe der .NET Framework-Basisunterstützung für Assemblyressourcen konfiguriert werden können (siehe Verwalten von Anwendungsressourcen).Während WPF-Ressourcendateien die .NET Framework-Basisunterstützung für eingebettete Ressourcen nutzen, gestaltet sich der Zugriff auf WPF-Ressourcendateien mithilfe von Paket-URIs einfacher als die Verwendung von Namespaces. |
Konfigurieren von Ressourcendateien
In WPF ist eine Ressourcendatei eine Datei, die als Resource-Element in ein Microsoft build engine (MSBuild)-Projekt eingefügt wird.
<Project "xmlns=https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Resource Include="ResourceFile.xaml" />
</ItemGroup>
...
</Project>
Hinweis |
---|
In Microsoft Visual Studio erstellen Sie eine Ressourcendatei, indem Sie einem Projekt eine Datei hinzufügen und Build Action auf Resource festlegen. |
Wenn das Projekt erstellt wird, kompiliert MSBuild die Ressource in die Assembly.
Verwenden von Ressourcendateien
Wenn Sie eine Ressourcendatei laden möchten, können Sie die GetResourceStream-Methode der Application-Klasse aufrufen, die einen Paket-URI übergibt, der die gewünschte Ressourcendatei identifiziert. GetResourceStream gibt ein StreamResourceInfo-Objekt zurück, das die Ressourcendatei als Stream verfügbar macht und den Inhaltstyp beschreibt.
Im folgenden Codebeispiel wird veranschaulicht, wie GetResourceStream zum Laden einer Page-Ressourcendatei verwendet und als Inhalt von Frame (pageFrame) festgelegt wird:
' 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
// 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;
Durch den Aufruf von GetResourceStream erhalten Sie zwar Zugriff auf Stream, es ist jedoch zusätzlicher Aufwand erforderlich, um ihn in den Typ der Eigenschaft zu konvertieren, mit der Sie ihn festlegen. Stattdessen kann WPF das Öffnen und Konvertieren von Stream übernehmen, indem eine Ressourcendatei mithilfe von Code direkt in die Eigenschaft eines Typs geladen wird.
Im folgenden Beispiel wird veranschaulicht, wie Sie Page mithilfe von Code direkt in Frame (pageFrame) laden.
Dim pageUri As New Uri("/PageResourceFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("/PageResourceFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Das folgende Beispiel entspricht dem Markup des vorangehenden Beispiels.
<Frame Name="pageFrame" Source="PageResourceFile.xaml" />
Anwendungscodedateien als Ressourcendateien
Auf einen speziellen Satz 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 Paket-URI festlegen, der auf das Fenster oder die Seite verweist, das bzw. die beim Starten einer Anwendung geladen werden soll.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="SOOPage.xaml" />
Diese Vorgehensweise bietet sich an, wenn eine XAML-Datei als Page-Element in ein Microsoft build engine (MSBuild)-Projekt eingefügt wird.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Page Include="MainWindow.xaml" />
</ItemGroup>
...
</Project>
Hinweis |
---|
In Visual Studio fügen Sie einem Projekt eine neue Window, NavigationWindow, Page, FlowDocument oder ResourceDictionary hinzu. Build Action für das Markup wird standardmäßig auf Page festgelegt. |
Wenn ein Projekt mit Page-Elementen kompiliert wird, werden die XAML-Elemente in das Binärformat konvertiert und in die zugeordnete Assembly kompiliert. Folglich können diese Dateien auf die gleiche Weise verwendet werden wie typische Ressourcendateien.
Hinweis |
---|
Wenn eine XAML-Datei als ein Resource-Element konfiguriert wird und über keine Code-Behind-Datei verfügt, wird die Rohdaten-XAML in eine Assembly und nicht in eine Binärversion der Rohdaten-XAML kompiliert. |
Inhaltsdateien
Eine Inhaltsdatei wird zusammen mit einer ausführbaren Assembly als lose Datei verteilt. Obwohl Assemblys nicht in eine Assembly kompiliert werden, werden sie mit Metadaten kompiliert, die eine Zuordnung mit den einzelnen Inhaltsdateien herstellen.
Verwenden Sie Inhaltsdateien, wenn die Anwendung einen speziellen Satz von Anwendungsdatendateien erfordert, die aktualisierbar sein soll, ohne dass die Assembly, die sie verwendet, neu kompiliert werden muss.
Konfigurieren von Inhaltsdateien
Um einem Projekt eine Inhaltsdatei hinzuzufügen, muss eine Anwendungsdatendatei als Content-Element enthalten sein. Da eine Inhaltsdatei nicht direkt in die Assembly kompiliert wird, müssen Sie außerdem das MSBuild CopyToOutputDirectory-Metadatenelement festlegen, um anzugeben, dass die Inhaltsdatei an einen Ort kopiert wird, der relativ zur erstellten Assembly ist. Wenn die Ressource beim Erstellen eines Projekts in den Buildausgabeordner kopiert werden soll, legen Sie das CopyToOutputDirectory-Metadatenelement mit dem Always-Wert fest. Andernfalls können Sie sicherstellen, dass lediglich die neueste Version der Ressource mithilfe des PreserveNewest-Wertes in den Buildausgabeordner kopiert wird.
Im Folgenden wird eine Datei gezeigt, die als Inhaltsdatei konfiguriert ist und nur dann in den Buildausgabeordner kopiert wird, wenn dem Projekt eine neue Version der Ressource hinzugefügt wird.
<Project xmlns="https://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 durch Hinzufügen einer Datei zu einem Projekt und Festlegen von Build Action auf Content und von Copy to Output Directory auf Copy always (entspricht Always) und Copy if newer (entspricht PreserveNewest). |
Beim Erstellen des Projekts wird ein AssemblyAssociatedContentFileAttribute-Attribut in die Metadaten der Assembly für jede Inhaltsdatei kompiliert.
[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]
Der Wert AssemblyAssociatedContentFileAttribute bedeutet, dass der Pfad zur Inhaltsdatei relativ zu deren Position im Projekt ist. Wenn sich eine Inhaltsdatei beispielsweise in einem Projektunterordner befand, werden die zusätzlichen Pfadinformationen in den AssemblyAssociatedContentFileAttribute-Wert integriert.
[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]
Der AssemblyAssociatedContentFileAttribute-Wert entspricht außerdem dem Wert des Pfades zur Inhaltsdatei im Buildausgabeordner.
Verwenden von Inhaltsdateien
Um eine Inhaltsdatei zu laden, können Sie die GetContentStream-Methode der Application-Klasse aufrufen. Dabei wird ein Paket-URI übergeben, der die gewünschte Inhaltsdatei identifiziert. GetContentStream gibt ein StreamResourceInfo-Objekt zurück, das die Inhaltsdatei als Stream verfügbar macht und den Inhaltstyp beschreibt.
Das folgende Codebeispiel veranschaulicht, wie Sie GetContentStream zum Laden einer Page-Inhaltsdatei verwenden und als Inhalt von Frame (pageFrame) festlegen.
' 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
// 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;
Durch den Aufruf von GetContentStream erhalten Sie zwar Zugriff auf Stream, es ist jedoch zusätzlicher Aufwand erforderlich, um ihn in den Typ der Eigenschaft zu konvertieren, mit der Sie ihn festlegen. Stattdessen kann WPF das Öffnen und Konvertieren von Stream übernehmen, indem eine Ressourcendatei mithilfe von Code direkt in die Eigenschaft eines Typs geladen wird.
Im folgenden Beispiel wird veranschaulicht, wie Sie Page mithilfe von Code direkt in Frame (pageFrame) laden.
Dim pageUri As New Uri("/PageContentFile.xaml", UriKind.Relative)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("/PageContentFile.xaml", UriKind.Relative);
this.pageFrame.Source = pageUri;
Das folgende Beispiel entspricht dem Markup des vorangehenden Beispiels.
<Frame Name="pageFrame" Source="PageContentFile.xaml" />
Dateien der Ursprungssite
Ressourcendateien sind durch eine explizite Beziehung an die Assemblys gebunden, mit denen sie entsprechend dem AssemblyAssociatedContentFileAttribute verteilt wurden. Es kann jedoch vorkommen, dass Sie eine implizite oder nicht vorhandene Beziehung zwischen einer Assembly und einer Anwendungsdatendatei herstellen, u. a. in folgenden Fällen:
Eine Datei ist zur Kompilierzeit nicht vorhanden.
Sie wissen bis zur Laufzeit nicht, welche Dateien von der Assembly benötigt werden.
Sie möchten in der Lage sein, Dateien ohne Neukompilierung der Assembly, der sie zugeordnet sind, zu aktualisieren.
Die Anwendung verwendet große Datendateien, z. B. Audio und Video. Diese sollen von Benutzern nur heruntergeladen werden, wenn sie dies wünschen.
Diese Dateitypen lassen sich mithilfe der bewährten URI-Schemas herunterladen, z. B. das file:///-Schema oder das http://-Schema.
<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />
Die Schemas file:/// und http:// erfordern jedoch volle Vertrauenswürdigkeit der Anwendung. Wenn die Anwendung eine XAML browser application (XBAP) ist und vom Internet oder Intranet aus gestartet wurde und nur diejenigen Berechtigungen anfordert, die für Anwendungen gewährt werden, die von diesen Orten aus gestartet werden, können lose Dateien nur von der Ursprungssite der Anwendung (Startspeicherort) aus geladen werden. Solche Dateien werden als Dateien der Ursprungssite bezeichnet.
Dateien der Ursprungssite stellen für teilweise vertrauenswürdige Anwendungen die einzige Option dar, obwohl sie nicht auf letztere beschränkt sind. Anwendungen mit voller Vertrauenswürdigkeit müssen ggf. Anwendungsdatendateien laden, die sie zur Buildzeit nicht kennen. Obwohl Anwendungen mit voller Vertrauenswürdigkeit file:/// verwenden könnten, ist anzunehmen, dass die Anwendungsdatendateien im selben Ordner oder in einem Unterordner der Anwendungsassembly installiert werden. In einem solchen Fall gestaltet sich die Verwendung des Verweises auf die Ursprungssite einfacher als die Verwendung von , da Sie für den vollständigen Dateipfad ausarbeiten müssen.
Hinweis |
---|
Dateien der Ursprungssite werden nicht mit einer XAML browser application (XBAP) auf einem Clientcomputer zwischengespeichert, Inhaltsdateien dagegen schon.Folglich werden sie nur heruntergeladen, wenn sie ausdrücklich angefordert werden.Wenn eine XAML browser application (XBAP)-Anwendung große Mediendateien enthält, führt die Konfiguration dieser Dateien als Dateien der Ursprungssite zu einem erheblich schnelleren Start der Originalanwendung. Außerdem werden die Dateien nur auf Anforderung heruntergeladen. |
Konfigurieren der Dateien der Ursprungssite
Wenn die Dateien der Ursprungssite zur Kompilierungszeit nicht vorhanden oder unbekannt sind, müssen Sie die bewährten Bereitstellungsmechanismen verwenden, um zu gewährleisten, dass die angeforderten Dateien zur Laufzeit verfügbar sind, einschließlich des XCopy-Befehlszeilenprogramms oder Microsoft Windows Installer.
Wenn Sie die Dateien, die auf der Ursprungssite gespeichert werden sollen, zur Kompilierungszeit kennen, aber dennoch explizite Abhängigkeit vermeiden möchten, können Sie diese Dateien einem Microsoft build engine (MSBuild)-Projekt als None-Element hinzufügen. Wie bei Inhaltsdateien müssen Sie das MSBuild CopyToOutputDirectory-Attribut festlegen, um anzugeben, dass die Datei der Ursprungssite an einen Speicherort kopiert wird, der relativ zur erstellten Assembly ist. Dabei wird entweder der Always-Wert oder der PreserveNewest-Wert angegeben.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<None Include="PageSiteOfOriginFile.xaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
...
</Project>
Hinweis |
---|
In Visual Studio erstellen Sie eine Datei der Ursprungssite, indem Sie einem Projekt eine Datei hinzufügen und seine Build Action auf None festlegen. |
Beim Erstellen des Projekts kopiert MSBuild die angegebenen Dateien in den Buildausgabeordner.
Verwenden der Dateien der Ursprungssite
Um eine Datei der Ursprungssite zu laden, können Sie die GetRemoteStream-Methode der Application-Klasse aufrufen. Dabei wird ein Paket-URI übergeben, der die gewünschte Datei der Ursprungssite identifiziert. GetRemoteStream gibt ein StreamResourceInfo-Objekt zurück, das die Datei der Ursprungssite als Stream verfügbar macht und den Inhaltstyp beschreibt.
Das folgende Codebeispiel veranschaulicht, wie GetRemoteStream zum Laden einer Page-Datei der Ursprungssite verwendet und als Inhalt von Frame (pageFrame) festgelegt wird.
' 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
// 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;
Durch den Aufruf von GetRemoteStream erhalten Sie zwar Zugriff auf Stream, es ist jedoch zusätzlicher Aufwand erforderlich, um ihn in den Typ der Eigenschaft zu konvertieren, mit der Sie ihn festlegen. Stattdessen kann WPF das Öffnen und Konvertieren von Stream übernehmen, indem eine Ressourcendatei mithilfe von Code direkt in die Eigenschaft eines Typs geladen wird.
Im folgenden Beispiel wird veranschaulicht, wie Sie Page mithilfe von Code direkt in Frame (pageFrame) laden.
Dim pageUri As New Uri("pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml", UriKind.Absolute)
Me.pageFrame.Source = pageUri
Uri pageUri = new Uri("pack://siteoforigin:,,,/SiteOfOriginFile.xaml", UriKind.Absolute);
this.pageFrame.Source = pageUri;
Das folgende Beispiel entspricht dem Markup des vorangehenden Beispiels.
<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
Neuerstellung nach Ändern des Buildtyps
Nachdem Sie den Buildtyp einer Anwendungsdatendatei geändert haben, müssen Sie die gesamte Anwendung neu erstellen, um zu gewährleisten, dass diese Änderungen übernommen werden. Wenn Sie nur die Anwendung erstellen, werden die Änderungen nicht übernommen.