Zasoby aplikacji WPF, zawartość, pliki danych

Aplikacje systemu Microsoft Windows często zależą od plików, które zawierają dane nie wykonywalne, takie jak Extensible Application Markup Language (XAML), obrazy, wideo i dźwięk. Program Windows Presentation Foundation (WPF) oferuje specjalną obsługę konfigurowania, identyfikowania i używania tych typów plików danych, które są nazywane plikami danych aplikacji. Ta obsługa koncentruje się wokół określonego zestawu typów plików danych aplikacji, w tym:

  • Pliki zasobów: pliki danych, które są kompilowane w zestawie wykonywalnym lub bibliotecznym WPF.

  • Pliki zawartości: autonomiczne pliki danych, które mają jawne skojarzenie z wykonywalnym zestawem WPF.

  • Lokacja plików pochodzenia: autonomiczne pliki danych, które nie mają skojarzenia z wykonywalnym zestawem WPF.

Jedną z ważnych różnic między tymi trzema typami plików jest to, że pliki zasobów i pliki zawartości są znane w czasie kompilacji; zestaw ma jawną wiedzę na ich temat. Jednak w przypadku plików pochodzenia zestaw może nie mieć żadnej wiedzy na ich temat lub niejawnej wiedzy za pośrednictwem odwołania do identyfikatora URI (URI) pakietu; przypadek drugiego, nie ma gwarancji, że faktycznie istnieje przywoływna lokacja pliku pochodzenia.

Aby odwołać się do plików danych aplikacji, program Windows Presentation Foundation (WPF) używa schematu identyfikatora URI (Pack uniform resource identifier), który został szczegółowo opisany w temacie Pack URIs in WPF (Pack URIs in WPF).

W tym temacie opisano sposób konfigurowania i używania plików danych aplikacji.

Pliki zasobów

Jeśli plik danych aplikacji musi być zawsze dostępny dla aplikacji, jedynym sposobem zagwarantowania dostępności jest skompilowanie go do głównego zestawu wykonywalnego aplikacji lub jednego z przywoływalnych zestawów. Ten typ pliku danych aplikacji jest nazywany plikiem zasobów.

Pliki zasobów należy używać w następujących przypadkach:

  • Nie trzeba aktualizować zawartości pliku zasobu po skompilowaniu go do zestawu.

  • Chcesz uprościć złożoność dystrybucji aplikacji, zmniejszając liczbę zależności plików.

  • Plik danych aplikacji musi być lokalizowalny (zobacz Omówienie globalizacji i lokalizacji WPF).

Uwaga

Pliki zasobów opisane w tej sekcji są inne niż pliki zasobów opisane w artykule Zasoby XAML i inne niż osadzone lub połączone zasoby opisane w temacie Zarządzanie zasobami aplikacji (.NET).

Konfigurowanie plików zasobów

W WPF plik zasobu jest plikiem dołączonym do projektu aparatu kompilacji firmy Microsoft (MSBuild) jako Resource elementu.

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

Uwaga

W programie Visual Studio tworzysz plik zasobów, dodając plik do projektu i ustawiając go Build Action na Resource.

Po skompilowaniu projektu program MSBuild kompiluje zasób do zestawu.

Korzystanie z plików zasobów

Aby załadować plik zasobu, możesz wywołać GetResourceStream metodę Application klasy, przekazując identyfikator URI pakietu identyfikujący żądany plik zasobu. GetResourceStreamStreamResourceInfo Zwraca obiekt, który uwidacznia plik zasobu jako Stream obiekt i opisuje jego typ zawartości.

Na przykład poniższy kod przedstawia sposób ładowania GetResourceStreamPage pliku zasobu i ustawiania go jako zawartości elementu 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

Wywołanie GetResourceStream zapewnia dostęp do Streamobiektu , należy wykonać dodatkową pracę konwersji na typ właściwości, za pomocą której zostanie ustawiona. Zamiast tego można pozwolić WPF dbać o otwieranie i konwertowanie Stream pliku zasobu przez załadowanie pliku zasobu bezpośrednio do właściwości typu przy użyciu kodu.

W poniższym przykładzie pokazano, jak załadować element Page bezpośrednio do elementu Frame (pageFrame) przy użyciu kodu.

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

Poniższy przykład jest odpowiednikiem znaczników poprzedniego przykładu.

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

Pliki kodu aplikacji jako pliki zasobów

Można odwoływać się do specjalnego zestawu plików kodu aplikacji WPF przy użyciu identyfikatorów URI pakietów, w tym okien, stron, dokumentów przepływu i słowników zasobów. Można na przykład ustawić Application.StartupUri właściwość za pomocą identyfikatora URI pakietu, który odwołuje się do okna lub strony, którą chcesz załadować po uruchomieniu aplikacji.

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

Można to zrobić, gdy plik XAML jest uwzględniony w projekcie MSBuild jako Page element.

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

Uwaga

W programie Visual Studio dodasz nowy Windowplik , , PageNavigationWindow, FlowDocumentlub ResourceDictionary do projektu .Build ActionPage

Po skompilowaniu projektu z elementami Page elementy XAML są konwertowane na format binarny i kompilowane w skojarzonym zestawie. W związku z tym te pliki mogą być używane w taki sam sposób, jak typowe pliki zasobów.

Uwaga

Jeśli plik XAML jest skonfigurowany jako Resource element i nie ma pliku za pomocą kodu, pierwotny kod XAML jest kompilowany w zestawie, a nie w wersji binarnej nieprzetworzonego kodu XAML.

Pliki zawartości

Plik zawartości jest dystrybuowany jako luźny plik wraz z zestawem wykonywalnym. Mimo że nie są one kompilowane w zestawie, zestawy są kompilowane z metadanymi, które ustanawia skojarzenie z każdym plikiem zawartości.

Pliki zawartości należy używać, gdy aplikacja wymaga określonego zestawu plików danych aplikacji, które mają być w stanie aktualizować bez ponownego komkompilowania zestawu, który z nich korzysta.

Konfigurowanie plików zawartości

Aby dodać plik zawartości do projektu, plik danych aplikacji musi być dołączony jako Content element. Ponadto, ponieważ plik zawartości nie jest kompilowany bezpośrednio w zestawie, należy ustawić element metadanych MSBuild CopyToOutputDirectory , aby określić, że plik zawartości jest kopiowany do lokalizacji, która jest względem wbudowanego zestawu. Jeśli chcesz, aby zasób był kopiowany do folderu wyjściowego kompilacji za każdym razem, gdy projekt jest kompilowany, należy ustawić CopyToOutputDirectory element metadanych z wartością Always . W przeciwnym razie możesz upewnić się, że tylko najnowsza wersja zasobu zostanie skopiowana do folderu wyjściowego kompilacji przy użyciu PreserveNewest wartości .

Poniżej przedstawiono plik skonfigurowany jako plik zawartości, który jest kopiowany do folderu wyjściowego kompilacji tylko wtedy, gdy do projektu zostanie dodana nowa wersja zasobu.

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

Uwaga

W programie Visual Studio tworzysz plik zawartości, dodając plik do projektu i ustawiając jego wartość na , i ustawiając jej Build ActionCopy to Output Directory wartość Copy always na (taką samą jak ) i Copy if newer (taką samą jak PreserveNewestAlways).Content

Po skompilowaniu AssemblyAssociatedContentFileAttribute projektu atrybut jest kompilowany w metadanych zestawu dla każdego pliku zawartości.

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

Wartość parametru AssemblyAssociatedContentFileAttribute oznacza ścieżkę do pliku zawartości względem jego pozycji w projekcie. Jeśli na przykład plik zawartości znajduje się w podfolderze projektu, dodatkowe informacje o ścieżce zostaną włączone do AssemblyAssociatedContentFileAttribute wartości.

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

Wartość AssemblyAssociatedContentFileAttribute jest również wartością ścieżki do pliku zawartości w folderze wyjściowym kompilacji.

Korzystanie z plików zawartości

Aby załadować plik zawartości, możesz wywołać GetContentStream metodę Application klasy, przekazując identyfikator URI pakietu identyfikujący żądany plik zawartości. GetContentStreamStreamResourceInfo Zwraca obiekt, który uwidacznia plik zawartości jako Stream obiekt i opisuje jego typ zawartości.

Na przykład poniższy kod pokazuje, jak załadować GetContentStream plik zawartości i ustawić Page go jako zawartość elementu 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

Wywołanie GetContentStream zapewnia dostęp do Streamobiektu , należy wykonać dodatkową pracę konwersji na typ właściwości, za pomocą której zostanie ustawiona. Zamiast tego można pozwolić WPF dbać o otwieranie i konwertowanie Stream pliku zasobu przez załadowanie pliku zasobu bezpośrednio do właściwości typu przy użyciu kodu.

W poniższym przykładzie pokazano, jak załadować element Page bezpośrednio do elementu Frame (pageFrame) przy użyciu kodu.

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

Poniższy przykład jest odpowiednikiem znaczników poprzedniego przykładu.

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

Witryna plików źródłowych

Pliki zasobów mają jawną relację z zestawami, które są dystrybuowane wraz z elementami zdefiniowanymi przez element AssemblyAssociatedContentFileAttribute. Jednak czasami może być konieczne ustanowienie niejawnej lub nieistniejącej relacji między zestawem a plikiem danych aplikacji, w tym w następujących przypadkach:

  • Plik nie istnieje w czasie kompilacji.

  • Nie wiesz, jakie pliki zestaw będzie wymagał do czasu wykonywania.

  • Chcesz mieć możliwość aktualizowania plików bez ponownego komplikowania zestawu, z którym są skojarzone.

  • Aplikacja używa dużych plików danych, takich jak audio i wideo, i chcesz, aby użytkownicy mogli je pobrać tylko wtedy, gdy zdecydują się.

Można załadować te typy plików przy użyciu tradycyjnych schematów identyfikatorów URI, takich jak file:///http:// i .

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

Jednak schematy file:/// i http:// wymagają, aby aplikacja miała pełne zaufanie. Jeśli aplikacja jest aplikacją przeglądarki XAML (XBAP), która została uruchomiona z Internetu lub intranetu, i żąda tylko zestawu uprawnień dozwolonych dla aplikacji uruchamianych z tych lokalizacji, luźne pliki mogą być ładowane tylko z witryny źródła aplikacji (lokalizacja uruchamiania). Takie pliki są nazywane witryną plików pochodzenia .

Lokacja plików pochodzenia jest jedyną opcją dla aplikacji częściowo zaufanych, chociaż nie jest ograniczona do aplikacji częściowo zaufanych. Aplikacje o pełnym zaufaniu mogą nadal wymagać załadowania plików danych aplikacji, o których nie wiedzą w czasie kompilacji; Chociaż aplikacje o pełnym zaufaniu mogą używać file:///, prawdopodobnie pliki danych aplikacji zostaną zainstalowane w tym samym folderze co podfolder zestawu aplikacji. W takim przypadku używanie odwołania do lokacji pochodzenia jest łatwiejsze niż użycie file:///, ponieważ użycie file:/// wymaga wypracowania pełnej ścieżki pliku.

Uwaga

Lokacja plików pochodzenia nie jest buforowana za pomocą aplikacji przeglądarki XAML (XBAP) na komputerze klienckim, podczas gdy pliki zawartości są. W związku z tym są pobierane tylko wtedy, gdy są one specjalnie żądane. Jeśli aplikacja przeglądarki XAML (XBAP) ma duże pliki multimedialne, skonfigurowanie ich jako lokacji plików pochodzenia oznacza, że początkowe uruchamianie aplikacji jest znacznie szybsze, a pliki są pobierane tylko na żądanie.

Konfigurowanie lokacji plików pochodzenia

Jeśli witryna plików pochodzenia nie istnieje lub nie jest znana w czasie kompilacji, należy użyć tradycyjnych mechanizmów wdrażania w celu zapewnienia, że wymagane pliki są dostępne w czasie wykonywania, w tym przy użyciu XCopy programu wiersza polecenia lub Instalatora Microsoft Windows.

Jeśli wiesz w czasie kompilacji pliki, które mają znajdować się w lokacji źródła, ale nadal chcesz uniknąć jawnej zależności, możesz dodać te pliki do projektu MSBuild jako None element. Podobnie jak w przypadku plików zawartości, należy ustawić atrybut MSBuild CopyToOutputDirectory , aby określić, że lokacja pliku pochodzenia jest kopiowana do lokalizacji powiązanej z utworzonym zestawem, określając Always wartość lub PreserveNewest wartość.

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

Uwaga

W programie Visual Studio tworzysz witrynę pliku pochodzenia, dodając plik do projektu i ustawiając jego Build Action wartość na None.

Podczas kompilowania projektu program MSBuild kopiuje określone pliki do folderu wyjściowego kompilacji.

Korzystanie z witryny plików źródłowych

Aby załadować lokację pliku pochodzenia, można wywołać GetRemoteStream metodę Application klasy, przekazując identyfikator URI pakietu identyfikujący żądaną lokację pliku pochodzenia. GetRemoteStream Zwraca obiekt, który uwidacznia witrynę StreamResourceInfo pliku pochodzenia jako Stream obiekt i opisuje jego typ zawartości.

Na przykład poniższy kod pokazuje, jak załadować witrynę Page pliku pochodzenia i ustawić GetRemoteStream ją jako zawartość elementu 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

Wywołanie GetRemoteStream zapewnia dostęp do Streamobiektu , należy wykonać dodatkową pracę konwersji na typ właściwości, za pomocą której zostanie ustawiona. Zamiast tego można pozwolić WPF dbać o otwieranie i konwertowanie Stream pliku zasobu przez załadowanie pliku zasobu bezpośrednio do właściwości typu przy użyciu kodu.

W poniższym przykładzie pokazano, jak załadować element Page bezpośrednio do elementu Frame (pageFrame) przy użyciu kodu.

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

Poniższy przykład jest odpowiednikiem znaczników poprzedniego przykładu.

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

Ponowne kompilowanie po zmianie typu kompilacji

Po zmianie typu kompilacji pliku danych aplikacji należy ponownie skompilować całą aplikację, aby upewnić się, że te zmiany zostaną zastosowane. Jeśli tylko skompilujesz aplikację, zmiany nie zostaną zastosowane.

Zobacz też