Arquivos de recursos, de conteúdo e de dados de aplicativos do WPF

Os aplicativos do Microsoft Windows geralmente dependem de arquivos que contêm dados não executáveis, como XAML (Extensible Application Markup Language), imagens, vídeo e áudio. O Windows Presentation Foundation (WPF) oferece suporte especial para configurar, identificar e usar esses tipos de arquivos de dados, que são chamados de arquivos de dados de aplicativo. Esse suporte gira em torno de um conjunto específico de tipos de arquivo de dados do aplicativo, incluindo:

  • Arquivos de Recursos: Arquivos de dados que são compilados em um assembly WPF executável ou de biblioteca.

  • Arquivos de conteúdo: arquivos de dados autônomos que têm uma associação explícita com um assembly WPF executável.

  • Arquivos do Site of Origin: arquivos de dados autônomos que não têm associação com um assembly WPF executável.

Uma distinção importante a se fazer entre esses três tipos de arquivos é que os arquivos de recurso e os arquivos de conteúdo são conhecidos em tempo de build; um assembly tem o conhecimento explícito sobre eles. Para arquivos de site de origem, no entanto, um assembly pode não ter nenhum conhecimento deles, ou conhecimento implícito por meio de uma referência de URI (identificador uniforme de recurso) do pacote; No caso deste último, não há garantia de que o arquivo de origem referenciado realmente exista.

Para fazer referência a arquivos de dados de aplicativo, o Windows Presentation Foundation (WPF) usa o esquema de identificador uniforme de recurso (URI) do Pack, que é descrito em detalhes em URIs do pacote no WPF).

Este tópico descreve como configurar e usar arquivos de dados do aplicativo.

Arquivos de recurso

Se um arquivo de dados do aplicativo precisar estar sempre disponível para um aplicativo, a única maneira de garantir essa disponibilidade será compilá-lo em um assembly executável principal do aplicativo ou em um de seus assemblies referenciados. Esse tipo de arquivo de dados do aplicativo é conhecido como um arquivo de recurso.

Você deve usar arquivos de recurso quando:

  • Você não precisa atualizar o conteúdo do arquivo de recurso depois que ele é compilado em um assembly.

  • Você deseja simplificar a complexidade da distribuição de aplicativos, reduzindo o número de dependências de arquivo.

  • O arquivo de dados do aplicativo precisa ser localizável (consulte Visão geral de localização e globalização do WPF).

Observação

Os arquivos de recurso descritos nesta seção são diferentes dos arquivos de recurso descritos em Recursos XAML e diferentes dos recursos incorporados ou vinculados descritos em Gerenciar Recursos de Aplicativo (.NET).

Configurando arquivos de recurso

No WPF, um arquivo de recurso é um arquivo que está incluído em um projeto de mecanismo de compilação da Microsoft (MSBuild) como um Resource item.

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

Observação

No Visual Studio, você cria um arquivo de recurso adicionando um arquivo a um projeto e definindo-o Build Action como Resource.

Quando o projeto é criado, o MSBuild compila o recurso no assembly.

Usando arquivos de recurso

Para carregar um arquivo de recurso, você pode chamar o GetResourceStreamApplication método da classe, passando um URI de pacote que identifica o arquivo de recurso desejado. GetResourceStream Retorna um objeto, que expõe o arquivo de recurso como um StreamResourceInfo e descreve seu tipo de Stream conteúdo.

Como exemplo, o código a seguir mostra como usar GetResourceStream para carregar um arquivo de recurso e defini-lo como o conteúdo de um PageFrame (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

Ao chamar GetResourceStream dá acesso ao Stream, você precisa executar o trabalho adicional de convertê-lo para o tipo de propriedade com o qual você irá configurá-lo. Em vez disso, você pode permitir que o WPF se encarregue de abrir e converter o Stream carregando um arquivo de recurso diretamente na propriedade de um tipo usando código.

O exemplo a seguir mostra como carregar um diretamente em um PageFrame (pageFrame) usando código.

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

O exemplo a seguir é um exemplo de marcação equivalente ao anterior.

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

Arquivos de código de aplicativo como arquivos de recurso

Um conjunto especial de arquivos de código de aplicativo WPF pode ser referenciado usando URIs de pacote, incluindo janelas, páginas, documentos de fluxo e dicionários de recursos. Por exemplo, você pode definir a Application.StartupUri propriedade com um URI de pacote que faz referência à janela ou página que você gostaria de carregar quando um aplicativo é iniciado.

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

Você pode fazer isso quando um arquivo XAML é incluído em um projeto MSBuild como um Page item.

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

Observação

No Visual Studio, você adiciona um novo Window, , , FlowDocumentou ResourceDictionary a um projeto, NavigationWindowPageo para o Build Action arquivo de marcação será padrão para Page.

Quando um projeto com Page itens é compilado, os itens XAML são convertidos em formato binário e compilados no assembly associado. Consequentemente, esses arquivos podem ser usados da mesma maneira que arquivos de recurso típicos.

Observação

Se um arquivo XAML estiver configurado como um item e não tiver um arquivo code-behind, o XAML bruto será compilado em um Resource assembly em vez de uma versão binária do XAML bruto.

Arquivos de Conteúdo

O arquivo de conteúdo é distribuído como arquivo flexível juntamente com um assembly executável. Embora eles não sejam compilados em um assembly, os assemblies são compilados com metadados que estabelecem uma associação com cada arquivo de conteúdo.

Você deve usar arquivos de conteúdo quando o aplicativo requer um conjunto específico de arquivos de dados do aplicativo que você deseja ser capaz de atualizar sem recompilar o assembly que os consome.

Configurando arquivos de conteúdo

Para adicionar um arquivo de conteúdo a um projeto, um arquivo de dados de 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ê precisa definir o elemento de metadados MSBuild CopyToOutputDirectory para especificar que o arquivo de conteúdo é copiado para um local relativo ao assembly criado. Se desejar que o recurso seja copiado para a pasta de saída da compilação sempre que um projeto for criado, defina o elemento de metadados com o CopyToOutputDirectoryAlways valor. Caso contrário, você pode garantir que apenas a versão mais recente do recurso seja copiada para a pasta de saída da compilação usando o PreserveNewest valor.

A seguir é mostrado um arquivo que está configurado como um arquivo de conteúdo que é copiado para a pasta de saída de build somente quando uma nova versão do recurso é adicionada ao projeto.

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

Observação

No Visual Studio, você cria um arquivo de conteúdo adicionando um arquivo a um projeto e definindo-o como , e defini-lo Build ActionCopy to Output Directory como ContentCopy always (igual a ) e Copy if newer (igual Alwaysa PreserveNewest).

Quando o projeto é criado, um AssemblyAssociatedContentFileAttribute atributo é compilado nos metadados do assembly para cada arquivo de conteúdo.

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

O valor do implica o caminho para o arquivo de AssemblyAssociatedContentFileAttribute conteúdo em relação à sua posição no projeto. Por exemplo, se um arquivo de conteúdo estivesse localizado em uma subpasta de projeto, as informações de caminho adicionais seriam incorporadas ao AssemblyAssociatedContentFileAttribute valor.

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

O AssemblyAssociatedContentFileAttribute valor também é o valor do caminho para o arquivo de conteúdo na pasta de saída da compilação.

Usando arquivos de conteúdo

Para carregar um arquivo de conteúdo, você pode chamar o GetContentStreamApplication método da classe, passando um URI de pacote que identifica o arquivo de conteúdo desejado. GetContentStream Retorna um objeto, que expõe o arquivo de conteúdo como um StreamResourceInfo e descreve seu tipo de Stream conteúdo.

Como exemplo, o código a seguir mostra como usar GetContentStream para carregar um arquivo de conteúdo e defini-lo como o conteúdo de um PageFrame (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

Ao chamar GetContentStream dá acesso ao Stream, você precisa executar o trabalho adicional de convertê-lo para o tipo de propriedade com o qual você irá configurá-lo. Em vez disso, você pode permitir que o WPF se encarregue de abrir e converter o Stream carregando um arquivo de recurso diretamente na propriedade de um tipo usando código.

O exemplo a seguir mostra como carregar um diretamente em um PageFrame (pageFrame) usando código.

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

O exemplo a seguir é um exemplo de marcação equivalente ao anterior.

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

Arquivos de site de origem

Os arquivos de recursos têm uma relação explícita com os assemblies que são distribuídos ao lado, conforme definido pelo AssemblyAssociatedContentFileAttribute. Mas, às vezes você deseja estabelecer um relacionamento implícito ou inexistente entre um assembly e um arquivo de dados do aplicativo, como quando:

  • Um arquivo não existe em tempo de compilação.

  • Você não sabe quais arquivos seu assembly vai requerer até o tempo de execução.

  • Você deseja ser capaz de atualizar os arquivos sem recompilar o assembly ao qual eles estão associados.

  • O aplicativo usa arquivos de dados grandes, como áudio e vídeo, e você só deseja que os usuários os baixem caso desejem.

É possível carregar esses tipos de arquivos usando esquemas de URI tradicionais, como os file:/// esquemas e http:// .

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

No entanto, os file:/// esquemas e http:// exigem que seu aplicativo tenha total confiança. Se seu aplicativo for um aplicativo de navegador XAML (XBAP) que foi iniciado a partir da Internet ou da intranet e solicitar apenas o conjunto de permissões permitidas para aplicativos iniciados a partir desses locais, os arquivos soltos só poderão ser carregados do site de origem do aplicativo (local de inicialização). Esses arquivos são conhecidos como arquivos de site de origem.

Os arquivos de site de origem são a única opção para aplicativos parcialmente confiáveis, apesar de não serem limitados a aplicativos parcialmente confiáveis. Os aplicativos de confiança total ainda podem precisar carregar arquivos de dados do aplicativo que eles não conhecem em tempo de build. Embora os aplicativos de confiança total possam utilizar file:///, é provável que os arquivos de dados do aplicativo sejam instalados na mesma pasta ou em uma subpasta do assembly do aplicativo. Nesse caso, usar a referência do site de origem é mais fácil do que usar file:///, porque o uso de file:/// requer que você descubra o caminho completo do arquivo.

Observação

Os arquivos do site de origem não são armazenados em cache com um aplicativo de navegador XAML (XBAP) em uma máquina cliente, enquanto os arquivos de conteúdo são. Consequentemente, eles são baixados somente quando solicitado especificamente. Se um aplicativo de navegador XAML (XBAP) tiver arquivos de mídia grandes, configurá-los como arquivos de site de origem significa que a inicialização inicial do aplicativo é muito mais rápida e os arquivos só são baixados sob demanda.

Configurando arquivos de site de origem

Se os arquivos do site de origem forem inexistentes ou desconhecidos em tempo de compilação, você precisará usar mecanismos de implantação tradicionais para garantir que os arquivos necessários estejam disponíveis em tempo de execução, incluindo o uso do XCopy programa de linha de comando ou do Microsoft Windows Installer.

Se você souber em tempo de compilação os arquivos que você gostaria de estar localizado no site de origem, mas ainda deseja evitar uma dependência explícita, você pode adicionar esses arquivos a um projeto MSBuild como None item. Assim como acontece com os arquivos de conteúdo, você precisa definir o atributo MSBuild CopyToOutputDirectory para especificar que o arquivo de origem do site seja copiado para um local relativo ao assembly criado, especificando o valor ou o PreserveNewestAlways valor.

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

Observação

No Visual Studio, você cria um site de arquivo de origem adicionando um arquivo a um projeto e definindo-o Build Action como None.

Quando o projeto é criado, o MSBuild copia os arquivos especificados para a pasta de saída da compilação.

Usando arquivos de site de origem

Para carregar um arquivo de site de origem, você pode chamar o GetRemoteStreamApplication método da classe, passando um URI de pacote que identifica o site desejado do arquivo de origem. GetRemoteStream Retorna um objeto, que expõe o arquivo Site of Origin como um StreamResourceInfoStream e descreve seu tipo de conteúdo.

Como exemplo, o código a seguir mostra como usar GetRemoteStream para carregar um arquivo de site de origem e defini-lo como o conteúdo de um PageFrame (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

Ao chamar GetRemoteStream dá acesso ao Stream, você precisa executar o trabalho adicional de convertê-lo para o tipo de propriedade com o qual você irá configurá-lo. Em vez disso, você pode permitir que o WPF se encarregue de abrir e converter o Stream carregando um arquivo de recurso diretamente na propriedade de um tipo usando código.

O exemplo a seguir mostra como carregar um diretamente em um PageFrame (pageFrame) usando código.

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

O exemplo a seguir é um exemplo de marcação equivalente ao anterior.

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

Recompilando após modificar o tipo de build

Depois de alterar o tipo de build de um arquivo de dados do aplicativo, você precisa recompilar o aplicativo inteiro para garantir que essas alterações sejam aplicadas. Se você apenas compilar o aplicativo, as alterações não serão aplicadas.

Confira também