Arquivos de recursos, conteúdo e dados do aplicativo 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 aplicativos. Esse suporte gira em torno de um conjunto específico de tipos de arquivos de dados de aplicativos, incluindo:
Resource Files: Arquivos de dados que são compilados em um assembly WPF executável ou de biblioteca.
Content Files: Arquivos de dados que são autónomos e têm uma associação explícita com um conjunto WPF executável.
Site of Origin Files: Arquivos de dados autónomos que não têm associação com um assembly WPF executável.
Uma distinção importante a fazer entre esses três tipos de arquivos é que os arquivos de recursos e arquivos de conteúdo são conhecidos no momento da compilação; uma assembleia tem conhecimento explícito deles. 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 de recurso uniforme) do pacote; No caso deste último, não há qualquer garantia de que o ficheiro do sítio de origem referenciado exista realmente.
Para fazer referência a arquivos de dados do aplicativo, o Windows Presentation Foundation (WPF) usa o esquema de URI (identificador uniforme de recursos) do Pack, que é descrito em detalhes em URIs do Pack no WPF).
Este tópico descreve como configurar e usar arquivos de dados do aplicativo.
Arquivos de recursos
Se um ficheiro de dados da aplicação tem de estar sempre disponível para a aplicação, a única forma de garantir a disponibilidade é compilá-lo no assembly executável principal da aplicação ou num dos seus assemblies referenciados. Esse tipo de arquivo de dados do aplicativo é conhecido como um arquivo de recurso .
Você deve usar arquivos de recursos quando:
Não é necessário atualizar o conteúdo do ficheiro de recursos depois de compilado num assembly.
Você deseja simplificar a complexidade da distribuição de aplicativos reduzindo o número de dependências de arquivos.
O arquivo de dados do aplicativo precisa ser localizável (consulte Visão geral da globalização e localização do WPF).
Observação
Os arquivos de recursos descritos nesta seção são diferentes dos arquivos de recursos descritos em de Recursos XAML e diferentes dos recursos incorporados ou vinculados descritos em Gerenciar Recursos de Aplicativo (.NET).
Configurando arquivos de recursos
No WPF, um arquivo de recurso é um arquivo que está incluído em um projeto do mecanismo de compilação da Microsoft (MSBuild) como um item Resource
.
<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 seu Build Action
para Resource
.
Quando o projeto é criado, MSBuild compila o recurso no assembly.
Usando arquivos de recursos
Para carregar um arquivo de recurso, você pode chamar o método GetResourceStream da classe Application, passando um URI de pacote que identifica o arquivo de recurso desejado. GetResourceStream retorna um objeto StreamResourceInfo, que expõe o arquivo de recurso como um Stream e descreve seu tipo de conteúdo.
Como exemplo, o código a seguir mostra como usar GetResourceStream para carregar um arquivo de recurso Page e defini-lo como o conteúdo de um 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
Embora a chamada GetResourceStream lhe dê acesso ao Stream, deves executar o trabalho adicional de convertê-lo para o tipo de propriedade ao qual o vais atribuir. Em vez disso, você pode permitir que o WPF cuide 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 Page diretamente em um Frame (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 é o equivalente em marcação do exemplo anterior.
<Frame Name="pageFrame" Source="PageResourceFile.xaml" />
Arquivos de código de aplicativo como arquivos de recursos
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 propriedade Application.StartupUri 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 item Page
.
<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, NavigationWindow, Page, FlowDocumentou ResourceDictionary a um projeto, o Build Action
para o arquivo de marcação será definido por defeito como Page
.
Quando um projeto com itens Page
é 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 os arquivos de recursos típicos.
Observação
Se um arquivo XAML estiver configurado como um item Resource
e não tiver um arquivo code-behind, o XAML bruto será compilado em um assembly em vez de uma versão binária do XAML bruto.
Arquivos de conteúdo
Um arquivo de conteúdo é distribuído como um arquivo solto ao lado de um assembly executável. Embora não sejam compilados num assemblage, os assemblages 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 seu aplicativo requer um conjunto específico de arquivos de dados da aplicação que você deseja poder atualizar sem recompilar o assembly que os utiliza.
Configurando arquivos de conteúdo
Para adicionar um arquivo de conteúdo a um projeto, um arquivo de dados do aplicativo deve ser incluído como um item de Content
. Além disso, como um arquivo de conteúdo não é compilado diretamente no assembly, você precisa definir o elemento de metadados do MSBuild CopyToOutputDirectory
para especificar que o arquivo de conteúdo seja copiado para um local relativo ao assembly compilado. 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 CopyToOutputDirectory
com o valor Always
. 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 valor PreserveNewest
.
A seguir mostra um arquivo que é configurado como um arquivo de conteúdo que é copiado para a pasta de saída de compilação 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 seu Build Action
como Content
e define sua Copy to Output Directory
como Copy always
(igual a Always
) e Copy if newer
(igual a PreserveNewest
).
Quando o projeto é criado, um atributo AssemblyAssociatedContentFileAttribute é compilado nos metadados do assembly para cada arquivo de conteúdo.
[assembly: AssemblyAssociatedContentFile("ContentFile.xaml")]
O valor do AssemblyAssociatedContentFileAttribute implica o caminho para o arquivo de conteúdo em relação à sua posição no projeto. Por exemplo, se um arquivo de conteúdo estivesse localizado em uma subpasta do projeto, as informações de caminho adicionais seriam incorporadas ao valor AssemblyAssociatedContentFileAttribute.
[assembly: AssemblyAssociatedContentFile("Resources/ContentFile.xaml")]
O valor AssemblyAssociatedContentFileAttribute também é o valor do caminho para o arquivo de conteúdo na pasta de saída da compilação.
Utilização de arquivos de conteúdo
Para carregar um arquivo de conteúdo, você pode chamar o método GetContentStream da classe Application, passando um URI de pacote que identifica o arquivo de conteúdo desejado. GetContentStream retorna um objeto StreamResourceInfo, que expõe o arquivo de conteúdo como um Stream e descreve seu tipo de conteúdo.
Como exemplo, o código a seguir mostra como usar GetContentStream para carregar um arquivo de conteúdo Page e defini-lo como o conteúdo de um 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
Embora a chamada GetContentStream lhe dê acesso ao Stream, você precisa executar o trabalho adicional de convertê-lo para o tipo de propriedade com o qual você o definirá. Em vez disso, você pode permitir que o WPF cuide 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 Page diretamente em um Frame (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 é o equivalente em linguagem de marcação do exemplo anterior.
<Frame Name="pageFrame" Source="PageContentFile.xaml" />
Arquivos do Site de Origem
Os arquivos de recursos têm uma relação explícita com as assemblagens com as quais são distribuídos, conforme definido pelo AssemblyAssociatedContentFileAttribute. Mas, há momentos em que você pode querer estabelecer uma relação implícita ou inexistente entre um assembly e um arquivo de dados do aplicativo, incluindo quando:
Um arquivo não existe em tempo de compilação.
Você não sabe quais ficheiros o seu assembly necessitará até o momento de execução.
Você deseja ser capaz de atualizar arquivos sem recompilar o assembly ao qual eles estão associados.
Seu aplicativo usa arquivos de dados grandes, como áudio e vídeo, e você só deseja que os usuários os baixem se assim desejarem.
É possível carregar esses tipos de arquivos usando esquemas de URI tradicionais, como os esquemas file:///
e http://
.
<Image Source="file:///C:/DataFile.bmp" />
<Image Source="http://www.datafilewebsite.com/DataFile.bmp" />
No entanto, os esquemas de file:///
e http://
exigem que seu aplicativo tenha total confiança. Se seu aplicativo for um aplicativo de navegador XAML (XBAP) que foi iniciado da Internet ou intranet e solicitar apenas o conjunto de permissões permitidas para aplicativos iniciados nesses 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 site de origem arquivos.
Os arquivos do site de origem são a única opção para aplicativos de confiança parcial, embora não estejam limitados a aplicativos de confiança parcial. Os aplicativos de confiança total ainda podem precisar carregar arquivos de dados do aplicativo que eles não conhecem no momento da compilação; Embora os aplicativos de confiança total possam usar 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 de site de origem é mais fácil do que usar file:///, porque usar file:/// requer que você descubra o caminho completo do arquivo.
Observação
Os ficheiros do site de origem não são armazenados em cache com uma aplicação de navegador XAML (XBAP) numa máquina cliente, enquanto os ficheiros de conteúdo o são. Consequentemente, só são descarregados quando especificamente solicitados. 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 do Site of Origin
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 programa de linha de comando XCopy
ou do Microsoft Windows Installer.
Se souber em tempo de compilação os ficheiros que gostaria que estivessem localizados no site de origem, mas ainda deseja evitar uma dependência explícita, pode adicionar esses ficheiros a um projeto MSBuild como item None
. Assim como acontece com os arquivos de conteúdo, você precisa definir o atributo CopyToOutputDirectory
MSBuild para especificar que o arquivo de site de origem seja copiado para um local relativo ao assembly compilado, especificando o valor Always
ou o valor PreserveNewest
.
<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 arquivo de site de origem adicionando um arquivo a um projeto e definindo seu Build Action
como None
.
Quando o projeto é criado, MSBuild copia os arquivos especificados para a pasta de saída de compilação.
Usando arquivos do Site of Origin
Para carregar um arquivo de site de origem, você pode chamar o método GetRemoteStream da classe Application, passando um URI de pacote que identifica o arquivo de site de origem desejado. GetRemoteStream retorna um objeto StreamResourceInfo, que expõe o arquivo do site de origem como um Stream e descreve seu tipo de conteúdo.
Como exemplo, o código a seguir mostra como usar GetRemoteStream para carregar um ficheiro do site de origem de Page e defini-lo como o conteúdo de um 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
Embora a chamada GetRemoteStream te dê acesso ao Stream, precisas realizar o trabalho adicional de o converter para o tipo de propriedade com o qual o vais definir. Em vez disso, você pode permitir que o WPF cuide 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 Page diretamente em um Frame (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 é o equivalente, em termos de marcação, do exemplo anterior.
<Frame Name="pageFrame" Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
Reconstruindo após alterar o tipo de compilação
Depois de alterar o tipo de compilação de um arquivo de dados do aplicativo, você precisa reconstruir 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.
Ver também
.NET Desktop feedback