Recursos, conteúdo e arquivos de dados de aplicativos WPF
Microsoft WindowsGeralmente, os aplicativos dependem arquivos que contêm dados não-executável, como Extensible Application Markup Language (XAML), imagens, vídeo e áudio. Windows Presentation Foundation (WPF)oferece suporte especial para configurar, identificando e uso desses tipos de arquivos de dados, que são chamados de arquivos de dados do aplicativo. This support revolves around a specific set of application data file types, including:
Arquivos de recurso: Os arquivos de dados são compilados em um executável ou uma biblioteca de WPF assembly.
Arquivos de conteúdo: Arquivos de dados autônomo que têm uma associação explícita com um executável WPF assembly.
Site de arquivos de origem: Os arquivos de dados autônomo não tem nenhuma associação com um executável WPF assembly.
One important distinction to make between these three types of files is that resource files and content files are known at build time; an assembly has explicit knowledge of them. For site of origin files, however, an assembly may have no knowledge of them at all, or implicit knowledge through a pack uniform resource identifier (URI) reference; the case of the latter, there is no guarantee that the referenced site of origin file actually exists.
To reference application data files, Windows Presentation Foundation (WPF) uses the Pack uniform resource identifier (URI) Scheme, which is described in detail in Pack URIs in WPF).
This topic describes how to configure and use application data files.
Este tópico contém as seguintes seções.
- Resource Files
- Content Files
- Site of Origin Files
- Rebuilding After Changing Build Type
- Tópicos relacionados
Resource Files
If an application data file must always be available to an application, the only way to guarantee availability is to compile it into an application's main executable assembly or one of its referenced assemblies. This type of application data file is known as a resource file.
You should use resource files when:
You don't need to update the resource file's content after it is compiled into an assembly.
You want to simplify application distribution complexity by reducing the number of file dependencies.
Your application data file needs to be localizable (see Visão geral de globalização e localização do WPF).
Observação
Resource dictionaries (XAML files with ResourceDictionary as their top-level element) are not WPF resource files; while WPF resource files can be resource dictionaries, a resource dictionary does not have to be a resource file (see ResourceDictionary).
Além disso, WPF arquivos de recursos não são iguais como o tipo de incorporadas ou vinculado de recursos que podem ser configuradas usando o núcleo .NET Framework suporte para recursos do assembly (consulte Gerenciando Recursos de Aplicativo).Enquanto WPF arquivos de recurso utilizam o núcleo .NET Framework suporte do recurso incorporado, a capacidade de acessar WPF arquivos de recursos usando o pacote URIs é mais fácil que usar espaços para nome.
Configuring Resource Files
In WPF, a resource file is a file that is included in an Microsoft build engine (MSBuild) project as a Resource item.
<Project "xmlns=https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Resource Include="ResourceFile.xaml" />
</ItemGroup>
...
</Project>
Observação
In Microsoft Visual Studio, you create a resource file by adding a file to a project and setting its Build Action to Resource.
When the project is built, MSBuild compiles the resource into the assembly.
Using Resource Files
Para carregar um arquivo de recurso, você pode chamar o GetResourceStream método de Application classe, passando de um pacote de URI que identifica o arquivo de recurso desejado. GetResourceStreamRetorna um StreamResourceInfo objeto, que expõe o arquivo de recurso como um Stream e descreve seu tipo de conteúdo.
As an example, the following code shows how to use GetResourceStream to load a Page resource file and set it as the content of a Frame (pageFrame):
' 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;
While calling GetResourceStream gives you access to the Stream, you need to perform the additional work of converting it to the type of the property that you'll be setting it with. Instead, you can let WPF take care of opening and converting the Stream by loading a resource file directly into the property of a type using code.
The following example shows how to load a Page directly into a Frame (pageFrame) using code.
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;
The following example is the markup equivalent of the preceding example.
<Frame Name="pageFrame" Source="PageResourceFile.xaml" />
Application Code Files as Resource Files
A special set of WPF application code files can be referenced using pack URIs, including windows, pages, flow documents, and resource dictionaries. For example, you can set the Application.StartupUri property with a pack URI that references the window or page that you would like to load when an application starts.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="SOOPage.xaml" />
You can do this when a XAML file is included in an Microsoft build engine (MSBuild) project as a Page item.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Page Include="MainWindow.xaml" />
</ItemGroup>
...
</Project>
Observação
In Visual Studio, you add a new Window, NavigationWindow, Page, FlowDocument, or ResourceDictionary to a project, the Build Action for the markup file will default to Page.
When a project with Page items is compiled, the XAML items are converted to binary format and compiled into the associated assembly. Consequently, these files can be used in the same way as typical resource files.
Observação
If a XAML file is configured as a Resource item, and does not have a code-behind file, the raw XAML is compiled into an assembly rather than a binary version of the raw XAML.
Content Files
A content file is distributed as a loose file alongside an executable assembly. Although they are not compiled into an assembly, assemblies are compiled with metadata that establishes an association with each content file.
You should use content files when your application requires a specific set of application data files that you want to be able to update without recompiling the assembly that consumes them.
Configuring Content Files
Para adicionar um arquivo de conteúdo a um projeto, um arquivo de dados do aplicativo deve ser incluído como um Content item. Além disso, como um arquivo de conteúdo não é compilado diretamente no assembly, você precisará definir o MSBuild CopyToOutputDirectory o elemento de metadados para especificar que o arquivo de conteúdo é copiado para um local que é relativo ao assembly compilado. If you want the resource to be copied to the build output folder every time a project is built, you set the CopyToOutputDirectory metadata element with the Always value. Otherwise, you can ensure that only the newest version of the resource is copied to the build output folder by using the PreserveNewest value.
The following shows a file that is configured as a content file which is copied to the build output folder only when a new version of the resource is added to the project.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<ItemGroup>
<Content Include="ContentFile.xaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
...
</Project>
Observação
In Visual Studio, you create a content file by adding a file to a project and setting its Build Action to Content, and set its Copy to Output Directory to Copy always (same as Always) and Copy if newer (same as PreserveNewest).
When the project is built, an AssemblyAssociatedContentFileAttribute attribute is compiled into the metadata of the assembly for each content file.
[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]
The value of the AssemblyAssociatedContentFileAttribute implies the path to the content file relative to its position in the project. For example, if a content file was located in a project subfolder, the additional path information would be incorporated into the AssemblyAssociatedContentFileAttribute value.
[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]
The AssemblyAssociatedContentFileAttribute value is also the value of the path to the content file in the build output folder.
Using Content Files
Para carregar um arquivo de conteúdo, você pode chamar o GetContentStream método de Application classe, passando de um pacote de URI que identifica o arquivo de conteúdo desejado. GetContentStreamRetorna um StreamResourceInfo objeto, que expõe o arquivo de conteúdo como um Stream e descreve seu tipo de conteúdo.
As an example, the following code shows how to use GetContentStream to load a Page content file and set it as the content of a Frame (pageFrame).
' 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;
While calling GetContentStream gives you access to the Stream, you need to perform the additional work of converting it to the type of the property that you'll be setting it with. Instead, you can let WPF take care of opening and converting the Stream by loading a resource file directly into the property of a type using code.
The following example shows how to load a Page directly into a Frame (pageFrame) using code.
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;
The following example is the markup equivalent of the preceding example.
<Frame Name="pageFrame" Source="PageContentFile.xaml" />
Site of Origin Files
Resource files have an explicit relationship with the assemblies that they are distributed alongside, as defined by the AssemblyAssociatedContentFileAttribute. But, there are times when you may want to establish either an implicit or non-existent relationship between an assembly and an application data file, including when:
A file doesn't exist when at compile time.
Você não sabe que seu conjunto exigirá até o tempo de execução de arquivos.
You want to be able to update files without recompiling the assembly that they are associated with.
Your application uses large data files, such as audio and video, and you only want users to download them if they choose to.
It is possible to load these types of files by using traditional URI schemes, such as the file:/// and http:// schemes.
<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />
However, the file:/// and http:// schemes require your application to have full trust. If your application is a XAML browser application (XBAP) that was launched from the Internet or intranet, and it requests only the set of permissions that are allowed for applications launched from those locations, loose files can only be loaded from the application's site of origin (launch location). Such files are known as site of origin files.
Site of origin files are the only option for partial trust applications, although are not limited to partial trust applications. Full trust applications may still need to load application data files that they do not know about at build time; while full trust applications could use file:///, it is likely that the application data files will be installed in the same folder as, or a subfolder of, the application assembly. In this case, using site of origin referencing is easier than using file:///, because using file:/// requires you to work out the full path the file.
Observação
Site of origin files are not cached with an XAML browser application (XBAP) on a client machine, while content files are.Consequently, they are only downloaded when specifically requested.If an XAML browser application (XBAP) application has large media files, configuring them as site of origin files means the initial application launch is much faster, and the files are only downloaded on demand.
Configuring Site of Origin Files
If your site of origin files are non-existent or unknown at compile time, you need to use traditional deployment mechanisms for ensuring the required files are available at run time, including using either the XCopy command-line program or the Microsoft Windows Installer.
If you do know at compile time the files that you would like to be located at the site of origin, but still want to avoid an explicit dependency, you can add those files to an Microsoft build engine (MSBuild) project as None item. Como com os arquivos de conteúdo, você precisará definir a MSBuild CopyToOutputDirectory atributo para especificar que o site do arquivo de origem é copiado para um local que é relativo ao assembly compilado, especificando um a Always valor ou a PreserveNewest valor.
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003" ... >
...
<None Include="PageSiteOfOriginFile.xaml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
...
</Project>
Observação
In Visual Studio, you create a site of origin file by adding a file to a project and setting its Build Action to None.
When the project is built, MSBuild copies the specified files to the build output folder.
Using Site of Origin Files
Para carregar um site do arquivo de origem, você pode chamar o GetRemoteStream método de Application classe, passando de um pacote de URI que identifica o site desejado do arquivo de origem. GetRemoteStreamRetorna um StreamResourceInfo objeto, que expõe o site do arquivo de origem como um Stream e descreve seu tipo de conteúdo.
As an example, the following code shows how to use GetRemoteStream to load a Page site of origin file and set it as the content of a Frame (pageFrame).
' 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;
While calling GetRemoteStream gives you access to the Stream, you need to perform the additional work of converting it to the type of the property that you'll be setting it with. Instead, you can let WPF take care of opening and converting the Stream by loading a resource file directly into the property of a type using code.
The following example shows how to load a Page directly into a Frame (pageFrame) using code.
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;
The following example is the markup equivalent of the preceding example.
<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
Rebuilding After Changing Build Type
After you change the build type of an application data file, you need to rebuild the entire application to ensure those changes are applied. If you only build the application, the changes are not applied.