URIs de pacote no WPF

No Windows Presentation Foundation (WPF), identificadores uniformes de recursos (URIs) são usados para identificar e carregar arquivos de várias maneiras, incluindo o seguinte:

  • Especificando a interface do usuário (UI) para mostrar quando um aplicativo é iniciado pela primeira vez.

  • Carregar imagens.

  • Navegar até as páginas.

  • Carregar arquivos de dados não executáveis.

Além disso, os URIs podem ser usados para identificar e carregar arquivos de vários locais, incluindo o seguinte:

  • O assembly atual.

  • Um assembly referenciado.

  • Um local relativo a um assembly.

  • O site de origem do aplicativo.

Para fornecer um mecanismo consistente para identificar e carregar esses tipos de arquivos desses locais, o WPF aproveita a extensibilidade do esquema de URI do pacote. Este tópico fornece uma visão geral do esquema, aborda como construir URIs de pacote para uma variedade de cenários, discute URIs absolutos e relativos e resolução de URIs, antes de mostrar como usar URIs de pacote de marcação e código.

O esquema de URI de pacote

O esquema de URI do pacote é usado pela especificação Open Packaging Conventions (OPC), que descreve um modelo para organizar e identificar conteúdo. Os principais elementos desse modelo são pacotes e peças, em que um pacote é um contêiner lógico para uma ou mais peças lógicas. A imagem a seguir ilustra esse conceito.

Package and Parts diagram

Para identificar peças, a especificação OPC aproveita a extensibilidade da RFC 2396 (URI (Uniform Resource Identifiers): sintaxe genérica) para definir o esquema de URI do pacote.

O esquema especificado por um URI é definido por seu prefixo; HTTP, FTP e File são exemplos bem conhecidos. O esquema de URI do pacote usa "pack" como seu esquema e contém dois componentes: autoridade e caminho. A seguir está o formato de um URI de pacote.

pack:// caminho da autoridade/

A autoridade especifica o tipo de pacote pelo qual uma peça é contida, enquanto o caminho especifica o local de uma peça dentro de um pacote.

Esse conceito é ilustrado pela figura a seguir:

Relationship among package, authority, and path

Os pacotes e peças são análogos a aplicativos e arquivos, pois um aplicativo (pacote) pode incluir um ou mais arquivos (peças), incluindo:

  • Arquivos de recursos que são compilados no assembly local.

  • Arquivos de recursos que são compilados em um assembly referenciado.

  • Arquivos de recursos que são compilados em um assembly de referência.

  • Arquivos de conteúdo.

  • Arquivos de site de origem.

Para acessar esses tipos de arquivos, o WPF oferece suporte a duas autoridades: application:/// e siteoforigin:///. A autoridade application:/// identifica arquivos de dados de aplicativo que são conhecidos no tempo de compilação, incluindo arquivos de recurso e conteúdo. A autoridade siteoforigin:/// identifica arquivos de site de origem. O escopo de cada autoridade é mostrado na figura a seguir.

Pack URI diagram

Observação

O componente de autoridade de um URI de pacote é um URI incorporado que aponta para um pacote e deve estar em conformidade com a RFC 2396. Além disso, o caractere “/” deve ser substituído pelo caractere “,”; caracteres reservados como “%” e “?” devem ser ignorados. Para ver os detalhes, consulte o OPC.

As seções a seguir explicam como construir URIs de pacote usando essas duas autoridades em conjunto com os caminhos apropriados para identificar arquivos de recurso, conteúdo e site de origem.

URIs de pacote de arquivo de recurso

Os arquivos de recursos são configurados como itens do MSBuild Resource e são compilados em assemblies. O WPF oferece suporte à construção de URIs de pacote que podem ser usados para identificar arquivos de recursos que são compilados no assembly local ou compilados em um assembly referenciado a partir do assembly local.

Arquivo de recurso de assembly local

O URI do pacote para um arquivo de recurso compilado no assembly local usa a seguinte autoridade e caminho:

  • Autoridade: application:///.

  • Caminho: o nome do arquivo de recurso, incluindo seu caminho, em relação à raiz da pasta de projeto do assembly local.

O exemplo a seguir mostra o URI do pacote para um arquivo de recurso XAML localizado na raiz da pasta de projeto do assembly local.

pack://application:,,,/ResourceFile.xaml

O exemplo a seguir mostra o URI do pacote para um arquivo de recurso XAML localizado em uma subpasta da pasta de projeto do assembly local.

pack://application:,,,/Subfolder/ResourceFile.xaml

Arquivo de recurso de assembly referenciado

O URI do pacote para um arquivo de recurso compilado em um assembly referenciado usa a seguinte autoridade e caminho:

  • Autoridade: application:///.

  • Caminho: o nome de um arquivo de recurso compilado em um assembly referenciado. O caminho deve estar de acordo com o seguinte formato:

    AssemblyShortName{; Versão]{; Chave Pública]; componente/caminho

    • AssemblyShortName: o nome curto do assembly referenciado.

    • ;Version [opcional]: a versão do assembly referenciado que contém o arquivo de recurso. É usada quando são carregados dois ou mais assemblies referenciados com o mesmo nome curto.

    • ;PublicKey [opcional]: a chave pública que foi usada para assinar o assembly referenciado. É usada quando são carregados dois ou mais assemblies referenciados com o mesmo nome curto.

    • ;component: especifica que o assembly referenciado é referenciado a partir do assembly local.

    • /Path: o nome do arquivo de recurso, incluindo o caminho, em relação à raiz da pasta de projeto do assembly referenciado.

O exemplo a seguir mostra o URI do pacote para um arquivo de recurso XAML localizado na raiz da pasta de projeto do assembly referenciado.

pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml

O exemplo a seguir mostra o URI do pacote para um arquivo de recurso XAML localizado em uma subpasta da pasta de projeto do assembly referenciado.

pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

O exemplo a seguir mostra o URI do pacote para um arquivo de recurso XAML localizado na pasta raiz da pasta de projeto de um assembly específico de versão referenciada.

pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml

Observe que a sintaxe de URI do pacote para arquivos de recurso de assembly referenciados pode ser usada somente com a autoridade application:///. Por exemplo, o seguinte não é suportado no WPF.

pack://siteoforigin:,,,/SomeAssembly;component/ResourceFile.xaml

URIs de pacote de arquivo de conteúdo

O URI do pacote para um arquivo de conteúdo usa a seguinte autoridade e caminho:

  • Autoridade: application:///.

  • Caminho: o nome do arquivo de conteúdo, incluindo o caminho em relação ao local do sistema de arquivos do principal assembly executável do aplicativo.

O exemplo a seguir mostra o URI do pacote para um arquivo de conteúdo XAML, localizado na mesma pasta do assembly executável.

pack://application:,,,/ContentFile.xaml

O exemplo a seguir mostra o URI do pacote para um arquivo de conteúdo XAML, localizado em uma subpasta relativa ao assembly executável do aplicativo.

pack://application:,,,/Subfolder/ContentFile.xaml

Observação

Arquivos de conteúdo HTML não podem ser navegados para. O esquema de URI só oferece suporte à navegação para arquivos HTML localizados no site de origem.

URIs de pacote de site de origem

O URI do pacote para um arquivo de site de origem usa a seguinte autoridade e caminho:

  • Autoridade: siteoforigin:///.

  • Caminho: o nome do arquivo de site de origem, incluindo o caminho em relação ao local a partir do qual o assembly executável foi iniciado.

O exemplo a seguir mostra o URI do pacote para um arquivo de origem do site XAML, armazenado no local a partir do qual o assembly executável é iniciado.

pack://siteoforigin:,,,/SiteOfOriginFile.xaml

O exemplo a seguir mostra o URI do pacote para um arquivo de origem do site XAML, armazenado em uma subpasta relativa ao local a partir do qual o assembly executável do aplicativo é iniciado.

pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml

Arquivos de paginação

Os arquivos XAML configurados como itens do MSBuild Page são compilados em assemblies da mesma forma que os arquivos de recurso. Consequentemente, os itens do MSBuild Page podem ser identificados usando URIs de pacote para arquivos de recurso.

Os tipos de arquivos XAML que são comumente configurados como itens do MSBuildPage têm um dos seguintes como seu elemento raiz:

URIs de pacote absoluto versus relativo

Um URI de pacote totalmente qualificado inclui o esquema, a autoridade e o caminho, e é considerado um URI de pacote absoluto. Como uma simplificação para desenvolvedores, os elementos XAML normalmente permitem que você defina atributos apropriados com um URI de pacote relativo, que inclui apenas o caminho.

Por exemplo, considere o seguinte URI de pacote absoluto para um arquivo de recurso no assembly local.

pack://application:,,,/ResourceFile.xaml

O URI do pacote relativo que se refere a esse arquivo de recurso seria o seguinte.

/ResourceFile.xaml

Observação

Como os arquivos de site de origem não estão associados a assemblies, eles só podem ser referenciados com URIs de pacote absoluto.

Por padrão, um URI de pacote relativo é considerado relativo ao local da marcação ou código que contém a referência. No entanto, se uma barra invertida à esquerda for usada, a referência de URI do pacote relativo será considerada relativa à raiz do aplicativo. Considere, por exemplo, a estrutura de projeto a seguir.

App.xaml

Page2.xaml

\SubFolder

+ Page1.xaml

+ Page2.xaml

Se Page1.xaml contiver um URI que faça referência a Root\SubFolder\Page2.xaml, a referência poderá usar o seguinte URI de pacote relativo.

Page2.xaml

Se Page1.xaml contiver um URI que faça referência a Root\Page2.xaml, a referência poderá usar o seguinte URI de pacote relativo.

/Page2.xaml

Resolução de URI de pacote

O formato de URIs de pacote possibilita que os URIs de pacote para diferentes tipos de arquivos tenham a mesma aparência. Por exemplo, considere o seguinte URI de pacote absoluto.

pack://application:,,,/ResourceOrContentFile.xaml

Esse URI de pacote absoluto pode se referir a um arquivo de recurso no assembly local ou a um arquivo de conteúdo. O mesmo é verdadeiro para o seguinte URI relativo.

/ResourceOrContentFile.xaml

Para determinar o tipo de arquivo ao qual um URI de pacote se refere, o WPF resolve URIs para arquivos de recurso em assemblies locais e arquivos de conteúdo usando as seguintes heurísticas:

  1. Examine os metadados do assembly em busca de um AssemblyAssociatedContentFileAttribute atributo que corresponda ao URI do pacote.

  2. Se o AssemblyAssociatedContentFileAttribute atributo for encontrado, o caminho do URI do pacote se refere a um arquivo de conteúdo.

  3. Se o AssemblyAssociatedContentFileAttribute atributo não for encontrado, examine os arquivos de recurso definidos que são compilados no assembly local.

  4. Se um arquivo de recurso que corresponde ao caminho do URI do pacote for encontrado, o caminho do URI do pacote se refere a um arquivo de recurso.

  5. Se o recurso não for encontrado, o criado Uri internamente será inválido.

A resolução de URI não se aplica a URIs que se referem ao seguinte:

  • Arquivos de conteúdo em assemblies referenciados: esses tipos de arquivo não são suportados pelo WPF.

  • Arquivos incorporados em assemblies referenciados: os URIs que os identificam são exclusivos porque incluem o nome do assembly referenciado e o sufixo ;component .

  • Arquivos de site de origem: os URIs que os identificam são exclusivos porque são os únicos arquivos que podem ser identificados por URIs de pacote que contêm a autoridade siteoforigin:///.

Uma simplificação que a resolução de URI do pacote permite é que o código seja um pouco independente dos locais dos arquivos de recurso e conteúdo. Por exemplo, se você tiver um arquivo de recurso no assembly local que é reconfigurado para ser um arquivo de conteúdo, o URI do pacote para o recurso permanece o mesmo, assim como o código que usa o URI do pacote.

Programando com URIs de pacote

Muitas classes WPF implementam propriedades que podem ser definidas com URIs de pacote, incluindo:

Essas propriedades podem ser definidas a partir de marcação e código. Esta seção demonstra as construções básicas para ambos e, depois, mostra exemplos de cenários comuns.

Utilizando URIs de pacote em marcação

Um URI de pacote é especificado na marcação definindo o elemento de um atributo com o URI do pacote. Por exemplo:

<element attribute="pack://application:,,,/File.xaml" />

A Tabela 1 ilustra os vários URIs de pacote absoluto que você pode especificar na marcação.

Tabela 1: URIs de pacote absolutos em marcação

Arquivo URI absoluto do pacote
Arquivo de recurso - assembly local "pack://application:,,,/ResourceFile.xaml"
Arquivo de recurso em subpasta - assembly local "pack://application:,,,/Subfolder/ResourceFile.xaml"
Arquivo de recurso - assembly referenciado "pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml"
Arquivo de recurso em subpasta de assembly referenciado "pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
Arquivo de recurso em assembly referenciado com controle de versão "pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml"
Arquivo de conteúdo "pack://application:,,,/ContentFile.xaml"
Arquivo de conteúdo em subpasta "pack://application:,,,/Subfolder/ContentFile.xaml"
Arquivo de site de origem "pack://siteoforigin:,,,/SOOFile.xaml"
Arquivo de site de origem em subpasta "pack://siteoforigin:,,,/Subfolder/SOOFile.xaml"

A Tabela 2 ilustra os vários URIs de pacote relativo que você pode especificar na marcação.

Tabela 2: URIs de pacote relativos em marcação

Arquivo URI do pacote relativo
Arquivo de recurso em assembly local "/ResourceFile.xaml"
Arquivo de recurso em subpasta de assembly local "/Subfolder/ResourceFile.xaml"
Arquivo de recurso em assembly referenciado "/ReferencedAssembly;component/ResourceFile.xaml"
Arquivo de recurso em subpasta de assembly referenciado "/ReferencedAssembly;component/Subfolder/ResourceFile.xaml"
Arquivo de conteúdo "/ContentFile.xaml"
Arquivo de conteúdo em subpasta "/Subfolder/ContentFile.xaml"

Utilizando URIs de pacote em código

Você especifica um URI de pacote no código instanciando a Uri classe e passando o URI do pacote como um parâmetro para o construtor. Isso é demonstrado no exemplo a seguir.

Uri uri = new Uri("pack://application:,,,/File.xaml");

Por padrão, a classe considera os Uri URIs de pacote como absolutos. Consequentemente, uma exceção é gerada quando uma instância da classe é criada com um URI de Uri pacote relativo.

Uri uri = new Uri("/File.xaml");

Felizmente, a Uri(String, UriKind)Uri sobrecarga do construtor de classe aceita um parâmetro de tipo UriKind para permitir que você especifique se um URI de pacote é absoluto ou relativo.

// Absolute URI (default)
Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute);
// Relative URI
Uri relativeUri = new Uri("/File.xaml",
                        UriKind.Relative);

Você deve especificar somente Absolute ou quando tiver certeza de que o URI do pacote fornecido é um ou Relative outro. Se você não souber o tipo de URI de pacote usado, como quando um usuário insere um URI de pacote em tempo de execução, use RelativeOrAbsolute em vez disso.

// Relative or Absolute URI provided by user via a text box
TextBox userProvidedUriTextBox = new TextBox();
Uri uri = new Uri(userProvidedUriTextBox.Text, UriKind.RelativeOrAbsolute);

A Tabela 3 ilustra os vários URIs de pacote relativo que você pode especificar no código usando System.Urio .

Tabela 3: URIs de pacote absolutos em código

Arquivo URI absoluto do pacote
Arquivo de recurso - assembly local Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute);
Arquivo de recurso em subpasta - assembly local Uri uri = new Uri("pack://application:,,,/Subfolder/ResourceFile.xaml", UriKind.Absolute);
Arquivo de recurso - assembly referenciado Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Absolute);
Arquivo de recurso em subpasta de assembly referenciado Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Absolute);
Arquivo de recurso em assembly referenciado com controle de versão Uri uri = new Uri("pack://application:,,,/ReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.Absolute);
Arquivo de conteúdo Uri uri = new Uri("pack://application:,,,/ContentFile.xaml", UriKind.Absolute);
Arquivo de conteúdo em subpasta Uri uri = new Uri("pack://application:,,,/Subfolder/ContentFile.xaml", UriKind.Absolute);
Arquivo de site de origem Uri uri = new Uri("pack://siteoforigin:,,,/SOOFile.xaml", UriKind.Absolute);
Arquivo de site de origem em subpasta Uri uri = new Uri("pack://siteoforigin:,,,/Subfolder/SOOFile.xaml", UriKind.Absolute);

A Tabela 4 ilustra os vários URIs de pacote relativo que você pode especificar no código usando System.Urio .

Tabela 4: URIs de pacote relativos em código

Arquivo URI do pacote relativo
Arquivo de recurso - assembly local Uri uri = new Uri("/ResourceFile.xaml", UriKind.Relative);
Arquivo de recurso em subpasta - assembly local Uri uri = new Uri("/Subfolder/ResourceFile.xaml", UriKind.Relative);
Arquivo de recurso - assembly referenciado Uri uri = new Uri("/ReferencedAssembly;component/ResourceFile.xaml", UriKind.Relative);
Arquivo de recurso em subpasta - assembly referenciado Uri uri = new Uri("/ReferencedAssembly;component/Subfolder/ResourceFile.xaml", UriKind.Relative);
Arquivo de conteúdo Uri uri = new Uri("/ContentFile.xaml", UriKind.Relative);
Arquivo de conteúdo em subpasta Uri uri = new Uri("/Subfolder/ContentFile.xaml", UriKind.Relative);

Cenários comuns de URI de pacote

As seções anteriores discutiram como construir URIs de pacote para identificar arquivos de recurso, conteúdo e site de origem. No WPF, essas construções são usadas de várias maneiras, e as seções a seguir cobrem vários usos comuns.

Especificando a interface do usuário para mostrar quando um aplicativo foi iniciado

StartupUri especifica a primeira interface do usuário a ser exibida quando um aplicativo WPF é iniciado. Para aplicativos autônomos, a interface do usuário pode ser uma janela, conforme mostrado no exemplo a seguir.

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

Aplicativos autônomos e aplicativos de navegador XAML (XBAPs) também podem especificar uma página como a interface do usuário inicial, conforme mostrado no exemplo a seguir.

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

Se o aplicativo for um aplicativo autônomo e uma página for especificada com StartupUri, o WPF abrirá um NavigationWindow para hospedar a página. Para XBAPs, a página é mostrada no navegador host.

O exemplo a seguir mostra como navegar até uma página.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page With Hyperlink"
  WindowWidth="250"
  WindowHeight="250">
<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
  Navigate to Another Page
</Hyperlink>
</Page>

Para obter mais informações sobre as várias maneiras de navegar no WPF, consulte Visão geral da navegação.

Especificando um ícone de janela

O exemplo a seguir mostra como usar um URI para especificar um ícone de janela.

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.MainWindow"
    Icon="WPFIcon1.ico">
</Window>

Para obter mais informações, consulte Icon.

Carregando arquivos de imagem, áudio e vídeo

O WPF permite que os aplicativos usem uma ampla variedade de tipos de mídia, todos os quais podem ser identificados e carregados com URIs de pacote, conforme mostrado nos exemplos a seguir.

<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/bee.wmv" />
<MediaElement Stretch="Fill" LoadedBehavior="Play" Source="pack://siteoforigin:,,,/Media/ringin.wav" />
<Image Source="Images/Watermark.png" />

Para obter mais informações sobre como trabalhar com conteúdo de mídia, consulte Elementos gráficos e multimídia.

Carregando um dicionário de recursos a partir do site de origem

Dicionários de recursos (ResourceDictionary) podem ser usados para dar suporte a temas de aplicativos. Uma maneira de criar e gerenciar temas é criando diferentes temas como dicionários de recursos localizados em um site de origem do aplicativo. Isso permite que temas sejam adicionados e atualizados sem recompilar e reimplantar um aplicativo. Esses dicionários de recursos podem ser identificados e carregados usando URIs de pacote, o que é mostrado no exemplo a seguir.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml">
  <Application.Resources>
    <ResourceDictionary Source="pack://siteoforigin:,,,/PageTheme.xaml" />
  </Application.Resources>
</Application>

Para obter uma visão geral dos temas no WPF, consulte Estilo e modelagem.

Confira também