Windows Dev Center

Referências de recursos de ResourceDictionary e XAML

O XAML define a interface de usuário do seu aplicativo, e o XAML também tem uma forma de definir recursos no XAML. Os recursos geralmente são definições de algum objeto que você espera usar mais de uma vez. Você especifica uma chave para um recurso XAML que age como seu nome para referências futuras. Você pode fazer referência a um recurso em uma aplicativo ou de qualquer página XAML dentro dele. O XAML do Tempo de Execução do Windows possui um elemento ResourceDictionary onde você define seus recursos. Então, você pode fazer referência aos seus recursos usando uma extensão de marcação StaticResource ou extensão de marcação ThemeResource.

Os elementos XAML que convém declarar com mais frequência como recursos XAML incluem Style, ControlTemplate, componentes de animação e subclasses Brush. Aqui, explicaremos como definir um ResourceDictionary e os recursos inseridos, e também como os recursos XAML se relacionam a outros recursos definidos como parte do aplicativo ou do pacote de aplicativos. Também explicaremos as funcionalidades avançadas do dicionário de recursos, como MergedDictionaries e ThemeDictionaries.

Pré-requisitos

Consideramos que compreende a marcação XAML e que tenha lido a Visão geral de XAML.

Recursos XAML devem ser compartilháveis

Para que um objeto exista em um ResourceDictionary, o objeto deve ser compartilhável.

A condição de compartilhável é uma exigência porque, quando a árvore de objetos de um aplicativo é construída e usada no tempo de execução, os objetos não podem existir em vários locais da árvore. Internamente, o sistema de recursos cria cópias de valores de recursos a serem utilizadas no gráfico de objeto de seu aplicativo quando cada recurso XAML é solicitado.

Um ResourceDictionary e o XAML do Tempo de Execução do Windows em geral dão suporte a esses objetos para uso compartilhável:

Também é possível usar tipos personalizados como um recurso compartilhável, se você seguir os padrões de implementação necessários. Você define essas classes em seu código de suporte (ou em componentes de tempo de execução que você inclui) e, depois, instancia essas classes no XAML como um recurso. Exemplos: fontes de dados de objeto e implementações IValueConverter para vinculação de dados.

Tipos personalizados devem ter um construtor padrão, porque é isso que um analisador XAML usa para instanciar uma classe. Tipos personalizados usados ​​como recursos não podem ter a classe UIElement em sua herança, porque o UIElement nunca pode ser compartilhável (é sempre destinado a representar exatamente um elemento da interface do usuário que existe em uma posição no gráfico de objeto do aplicativo em tempo de execução).

Chaves para recursos

Cada item em um ResourceDictionary deve ter uma chave definida. Um ResourceDictionary é realmente um dicionário, em termos de programação. Geralmente, você define chaves para XAML recursos que usam o atributo x:Key. Existem todos os tipos de objetos que podem possivelmente ser um recurso XAML e esses objetos não compartilham quaisquer propriedades comuns do Tempo de Execução do Windows. Portanto, para que se possa colocar essa ampla gama de recursos possíveis em um dicionário de recurso, o atributo x:Key é definido globalmente pela linguagem XAML, e pode ser aplicado legalmente a qualquer elemento de objeto XAML que seja encontrado em um dicionário.

A x:Key torna-se a chave do item de dicionário, e os outros valores em XAML definem um objeto que é o valor do item do dicionário.

Recursos para XAML de Tempo de Execução do Windows devem usar cadeias de caracteres nos nomes de chaves. Especificamente, a cadeia de caracteres deve seguir as regras de gramática de XamlName; veja a seção "Gramática de XamlName" da página de referência do atributo x:Key.

Se você incluir um item em um ResourceDictionary e o item não tiver uma chave que possa ser utilizada, ocorrerá um erro de análise XAML quando o aplicativo tentar examinar o item de recurso. Se você duplicar uma chave, ocorrerá um erro de análise de XAML. O Microsoft Visual Studio e respectiva área de design XAML geralmente podem fornecer comentários sobre o tempo de design, caso ocorram problemas de definição e referência de recurso no XAML. Entretanto, se o designer XAML não puder fornecer um aviso, os problemas de definição de recurso XAML poderão ser relatados como erros ou exceções quando o aplicativo tentar carregar o XAML no tempo de execução.

Chaves implícitas para modelos de controles e estilos

Modelos de controle e Style elementos com uma propriedade TargetType são casos especiais em que o valor de um atributo x:Key não é necessário para que ele exista como um recurso XAML. Para esses tipos, a chave do recurso é implícita. O valor da chave implícita se baseia em uma forma de cadeia de caracteres do valor TargetType declarado no modelo ou estilo, e essa chave é usada pela lógica de controle do XAML no tempo de execução como a pesquisa implícita para o estilo ou modelo a ser aplicado a um controle específico. Por exemplo, um Style que tenha TargetType="Button" pode ser o estilo implícito de todos os controles Button em seu aplicativo, sem requerer uma chave para a definição do recurso ou uma referência StaticResource de cada Button. Para saber mais sobre estilos implícitos, veja Início rápido: Modelos de controle.

Recursos de storyboard

Um recurso Storyboard é um outro caso especial em que um Storyboard pode existir em um ResourceDictionary sem um valor x:Key, desde que ele tenha um valor x:Name. Em geral, a intenção de se colocar um Storyboard em um ResourceDictionary não é a de que ele seja reutilizável, pois as animações contidas já estão direcionando propriedades específicas. Em vez disso, um ResourceDictionary é apenas um contêiner XAML conveniente para colocar os vários elementos Storyboard. No devido tempo, você fará referência às instâncias de Storyboard por nome e chamará seus métodos Begin. Isto é geralmente feito a partir do code-behind em resposta a eventos como Loaded ou vinculados a eventos iniciados pelo usuário. Para saber mais, veja Animações com storyboard.

Recursos imediatos e de aplicativo

Existem duas propriedades para aplicativos típicos que contêm os nós ResourceDictionary onde você definirá recursos XAML: FrameworkElement.Resources e Application.Resources.

FrameworkElement.Resources fornece recursos imediatos. Recursos imediatos também são chamados, às vezes, de recursos de página. No XAML, é possível usar a técnica de referência imediata para referenciar os recursos XAML no FrameworkElement.Resources em qualquer objeto conectado à mesma árvore de objetos. Basicamente, isso significa a mesma página XAML, pois geralmente você define o valor FrameworkElement.Resources no elemento raiz de uma página XAML, onde todos os elementos XAML possíveis na página podem encontrá-lo.

Application.Resources fornece recursos no nível do aplicativo. Os recursos definidos por Application.Resources são disponibilizados em qualquer página ou em outras interfaces do usuário carregadas como o Window.Content atual do aplicativo. A especificação de recursos no nível do aplicativo poderá ser útil se você carregar diferentes páginas no Window.Content para dar suporte à navegação, e quiser evitar a duplicação dos mesmos recursos em cada página. Além disso, se você estiver adicionando pares chave/valor (recursos) a um ResourceDictionary no tempo de execução de forma que as páginas carregadas mais tarde possam encontrá-los, o escopo do aplicativo oferecerá um local onde esses recursos possam persistir durante o tempo de vida do aplicativo.

Um terceiro local para os recursos faz parte do estilo padrão de um controle, empacotado juntamente com controle. Esse local destina-se apenas para pesquisa do recurso inserido pelo valor DefaultStyleKey do controle.

Observação   Não confunda os conceitos relacionados ao ResourceDictionary com a ação de compilação Resource, com arquivos de recursos (.resw) ou com outros "recursos" que são abordados no contexto de estruturação do projeto de código que produz o seu pacote de aplicativo. Para saber mais sobre os conceitos globais de recursos de aplicativos, veja Definindo recursos do aplicativo e Como se preparar para a localização.

Referenciando recursos do XAML

No XAML, para fazer referência a um recurso XAML existente de um ResourceDictionary, use a extensão de marcação StaticResource ou a extensão de marcação ThemeResource. Nesta documentação, elas são chamadas de referências de recurso XAML. Para usar uma referência de recurso XAML com as extensões de marcação, você sempre faz referência da propriedade que está definindo a um uso de atributo.

Veja a seguir um XAML de exemplo. Para definir o valor da propriedade Background de um Button para usar um recurso estático chamado fadeBrush, primeiro você precisa declarar esse recurso com uma chave e depois fazer referência a ele com base nessa chave.


<ResourceDictionary>
...
  <LinearGradientBrush x:Key="fadeBrush">
    <GradientStop Color="Red" Offset="0"/>
    <GradientStop Color="Gray" Offset="1"/>
  </LinearGradientBrush>
</ResourceDictionary>
...
 <!--XAML within a UserControl or some other root container tag that defines app UI-->
<Button Background="{StaticResource fadeBrush}" .../>


No exemplo precedente, as duas partes do XAML podiam não estar no mesmo arquivo XAML. O ResourceDictionary podia ser definido em Application.Resources, em um arquivo de dicionário de temas ou em um dicionário mesclado.

Use a sintaxe de atributo XAML para criar uma referência de atributo XAML, mesmo que a propriedade que está sendo configurada exija um uso de elemento de propriedade no XAML. Por exemplo, veja a seguir um uso de elemento de propriedade equivalente, que mostra o LinearGradientBrush definido de modo embutido, e não como um recurso ResourceDictionary.


<Button>
  <Button.Background>
    <LinearGradientBrush>
      <GradientStop Color="Red" Offset="0"/>
      <GradientStop Color="Gray" Offset="1"/>
    </LinearGradientBrush>
  </Button.Background>
</Button>

Comportamento de pesquisa para referências de recursos XAML

O comportamento de pesquisa é o termo para como o sistema de recursos XAML tenta encontrar um recurso XAML. A pesquisa acontece para uma chave referenciada como uma referência de recurso XAML de algum lugar no XAML do aplicativo. O sistema de recursos tem um comportamento previsível no que diz respeito a onde ele verificará a existência de um recurso com base no escopo. Se um recurso não for encontrado no escopo inicial, o escopo será expandido. O comportamento de pesquisa continua em todas as localizações e escopos em que um recurso XAML poderia ser definido por um aplicativo ou pelo sistema. Se todas as tentativas de pesquisa de recursos possíveis falharem, em geral um erro será gerado. Normalmente, é possível eliminar esses erros durante o processo de desenvolvimento.

O comportamento de pesquisa para referências de recursos XAML começa com o objeto em que o uso real foi aplicado e sua respectiva propriedade Resources. Se houver um ResourceDictionary, esse ResourceDictionary será verificado para obter um item que tenha a chave solicitada. Esse primeiro nível de pesquisa raramente é relevante porque, em geral, você não define e depois referencia um recurso no mesmo objeto. De fato, uma propriedade Resources não existe aqui. É possível fazer referências a recursos XAML praticamente de qualquer lugar do XAML; você não está limitado às propriedades de subclasses FrameworkElement.

A sequência de pesquisa verifica o próximo objeto pai na árvore de objetos do tempo de execução do aplicativo. Se FrameworkElement.Resources existir e contiver um ResourceDictionary, o item de dicionário com a cadeia de caracteres da chave especificada será solicitado. Se o recurso for encontrado, a sequência de pesquisa será interrompida e o objeto será fornecido ao local onde a referência foi feita. Caso contrário, o comportamento de pesquisa avançará para o próximo nível pai, em direção da raiz da árvore de objetos. A pesquisa continuará recursivamente para cima até que o elemento raiz do XAML seja alcançado, esgotando a pesquisa de todos os possíveis locais de recursos imediatos.

Observação  É prática comum definir todos os recursos imediatos no nível da raiz de uma página, tanto para obter as vantagens desse comportamento de pesquisa de recursos como também como uma convenção do estilo de marcação XAML.

Se o recurso solicitado não for encontrado nos recursos imediatos, a próxima etapa de pesquisa será verificar a propriedade Application.Resources. Application.Resources é o melhor lugar para colocar qualquer recurso específico do aplicativo que seja referenciado por várias páginas, na estrutura de navegação do aplicativo.

Os modelos de controles têm outro possível local na pesquisa de referência: os dicionários de temas. Um dicionário de temas é um único arquivo XAML que tem o elemento ResourceDictionary como raiz. O dicionário de temas pode ser um dicionário mesclado de Application.Resources. O dicionário de temas também pode ser o dicionário de temas específico de um controle modelo personalizado.

Por fim, há uma pesquisa baseada nos recursos de plataforma. Os recursos de plataforma incluem os modelos de controle definidos para cada um dos temas da interface do usuário do sistema e que definem a aparência padrão de todos os controles usados na interface do usuário de um aplicativo do Tempo de Execução do Windows. Os recursos da plataforma também incluem um conjunto de recursos nomeados que se relacionam à aparência e aos temas em todo o sistema. Esses recursos são tecnicamente um item MergedDictionaries e estão disponíveis para pesquisa de XAML ou código depois que o aplicativo é carregado. Por exemplo, os recursos de tema do sistema incluem um recurso chamado "SystemColorWindowTextColor" que oferece uma definição de Color para combinar a cor do texto do aplicativo com a cor do texto da janela do sistema que vem do sistema operacional e das preferências do usuário. Outros estilos XAML em seu aplicativo podem mencionar esse estilo, ou o seu código pode obter um valor da pesquisa de recurso (e convertê-lo emColor no caso do exemplo).

Para saber mais e obter uma lista dos recursos do sistema e dos recursos específicos de temas que estão disponíveis para um aplicativo da Windows Store em XAML, veja a Referência de recursos de temas XAML.

Se a chave solicitada ainda assim não for encontrada nesses locais, ocorrerá um erro/exceção de análise XAML. Em determinadas circunstâncias, a exceção de análise XAML pode ser uma exceção de tempo de execução que não é detectada nem pela ação de compilação de marcação XAML, nem pelo ambiente de design XAML.

Devido ao comportamento de pesquisa em níveis dos dicionários de recursos, é possível definir deliberadamente vários itens de recursos, cada um deles com o mesmo valor de cadeia de caracteres como a chave, desde que cada recurso seja definido em um nível diferente. Ou seja, embora as chaves devam ser exclusivas em qualquer ResourceDictionary fornecido, a exigência de exclusividade não se estende à sequência do comportamento de pesquisa como um todo. Durante a pesquisa, apenas o primeiro objeto recuperado com êxito é usado para a referência de recurso XAML e, em seguida, a pesquisa para. Você poderia usar esse comportamento para solicitar o mesmo recurso XAML por chave em várias posições dentro do XAML de seu aplicativo, mas obter recursos diferentes de volta, dependendo do escopo do qual a referência do recurso XAML foi feita e como essa pesquisa específica se comporta.

Dicionários de recursos mesclados

Um dicionário de recursos mesclado permite declarar o conteúdo de um dicionário de recursos por meio de referenciação a um arquivo externo; habilita também o uso de recursos definidos externamente para aumentar os recursos encontrados em uma propriedade Resources. Os usos do dicionário de recursos mesclado alteram duas características dos dicionários de recursos: a sequência de pesquisa e as exigências de exclusividade da chave em um escopo.

Para declarar um dicionário de recursos mesclado, adicione um elemento da propriedade MergedDictionaries a um elemento ResourceDictionary existente. É possível adicionar MergedDictionaries às propriedades FrameworkElement.Resources ou Application.Resources Ia mesclagem em Application.Resources é mais usual).

Você precisa declarar explicitamente o ResourceDictionary como um elemento de objeto para poder usar o elemento de propriedade ResourceDictionary.MergedDictionary contido no dicionário. O ResourceDictionary existente pode ter outros recursos inseridos, além do elemento de propriedade MergedDictionaries. O conteúdo de um elemento de propriedade XAML de MergedDictionaries inclui um ou mais itens do ResourceDictionary declarados como elementos de objeto XAML. Os elementos do ResourceDictionary que representam dicionários mesclados não podem conter recursos inseridos adicionais. Em vez disso, esses elementos do ResourceDictionary devem declarar apenas um atributo: Source. O valor Source indica o modo como você referencia o local externo do dicionário de recursos.

Por exemplo, o seguinte XAML define um ResourceDictionary com um recurso inserido e uma coleção de MergedDictionaries que faz referência a dois arquivos XAML de dicionário de recursos diferentes.


<Application.Resources>
    <ResourceDictionary>
      <!--other resources can be here-->
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="rd1.xaml" />
        <ResourceDictionary Source="rd2.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>

Você pode especificar mais de um ResourceDictionary nos MergedDictionaries. Na sequência de pesquisa de recursos, um dicionário MergedDictionaries só é verificado depois da verificação de todos os recursos inseridos do ResourceDictionary. Depois, pesquisando esse nível, a pesquisa acessa os dicionários mescladols, e cada item em MergedDictionaries é verificado. Se houver vários dicionários mesclados, eles serão verificados na ordem inversa em que foram declarados na propriedade MergedDictionaries. No exemplo precedente, se "rd2.xaml" e "rd1.xaml" tiverem declarado a mesma chave, a chave de "rd2.xaml" será usada primeiro porque é a última no conjunto de MergedDictionaries.

No escopo de qualquer ResourceDictionary, o dicionário é verificado para confirmar a exclusividade da chave. Entretanto, esse escopo não se estende pelos vários itens em arquivos diferentes de MergedDictionaries.

É possível usar a combinação da sequência de pesquisa e a ausência de imposição de chave exclusiva nos escopos de dicionários mesclados para criar uma sequência de valores de fallback dos recursos do ResourceDictionary. Por exemplo, você pode armazenar as preferências do usuário para uma determinada cor do pincel no último dicionário de recursos mesclado na sequência, usando um dicionário de recursos que é sincronizado com o estado de seu aplicativo e dados de preferência do usuário. No entanto, se não houver qualquer preferência de usuário, você poderá definir essa mesma cadeia de caracteres da chave para um recurso do ResourceDictionary no arquivo MergedDictionaries inicial, e isso poderá servir como o valor de fallback. Lembre-se de que qualquer valor fornecido em um dicionário de recursos principal é sempre verificado antes da verificação dos dicionários mesclados, portanto, se quiser usar a técnica de fallback, não defina esse recurso em um dicionário de recursos principal.

Dicionários de temas

Um dicionário de temas é um tipo especial de dicionário mesclado, cujo propósito é manter os recursos que variam conforme o tema usado pelo usuário no momento, em seu computador. Por exemplo, o tema "claro" pode usar uma cor branca, enquanto o tema padrão talvez use um pincel de cor escura. O pincel muda o recurso para o qual ele resolvido, mas de outra modo a composição de um controle que usa o pincel como um recurso poderia ser a mesma. Para reproduzir o comportamento de alternância de tema em seus próprios modelos e estilos, em vez de usar MergedDictionaries como a propriedade para mesclar os itens nos dicionários principais, use a propriedade ThemeDictionaries. Assim como nos MergedDictionaries, você define essa propriedade usando a sintaxe de elemento de propriedade; o valor da propriedade é um ou mais dos elementos de objeto do ResourceDictionary.

Cada elemento do ResourceDictionary em ThemeDictionaries deve ter um valor x:Key. Esse valor é uma cadeia de caracteres que nomeia o tema relevante —, por exemplo, "Default", "Light" ou "HighContrast".

Os elementos contidos no ResourceDictionary podem usar um destes dois modelos:

  • O ResourceDictionary tem um único atributo Source e nenhum outro conteúdo. O atributo Source se refere a um arquivo XAML separado, que contém apenas uma raiz do ResourceDictionary. Esse dicionário então define os itens inseridos e que são específicos do tema que está sendo nomeado pelo valor x:Key no elemento do ResourceDictionary que especificou Source. Valor Source geralmente referencia um arquivo XAML na estrutura do projeto e no pacote de aplicativos.
  • O conteúdo doResourceDictionary são os itens inseridos e específicos do tema que foi nomeado pelo valor x:Key no elemento pai ResourceDictionary.

Da mesma maneira que nos dicionários mesclados, é legítima a definição da mesma chave várias vezes em um conjunto de dicionários de temas na mesma coleção ThemeDictionaries, desde que ela seja exclusiva em cada unidade de ResourceDictionary. Na verdade, este é o design pretendido: cada dicionário de temas deve ter um conjunto idêntico de chaves. Caso contrário, qualquer tema que não tiver uma das chaves provavelmente causará um problema de interface do usuário quando for carregado. Diferentemente dos dicionários mesclados, a ordem de definição de cada tema não é importante. Para dicionários de temas, o dicionário ativo que será usado para pesquisa de recursos muda dinamicamente, sempre que a extensão de marcação ThemeResource é usada para fazer a referência e o sistema detecta uma mudança no tema. O comportamento da pesquisa feita pelo sistema se baseia no mapeamento do tema ativo para o x:Key de um dicionário de tema específico.

Pode ser útil examinar como os dicionários de temas estão estruturados nos recursos de design de XAML padrão, que são correspondentes aos modelos que o Tempo de Execução do Windows usa por padrão para seus controles. Use um editor de texto ou editores semelhantes no IDE para abrir os arquivos XAML em \(Program Files)\Windows Kits\<version>\Include\winrt\xaml\design. Observe como os dicionários de temas são definidos primeiro em generic.xaml e como cada dicionário de temas define as mesmas chaves. Cada uma dessas chaves é então referenciada pelos elementos de composição nos vários elementos inseridos, os quais estão fora do dicionário de temas e foram definidos posteriormente no XAML. Há também um arquivo themeresources.xaml à parte para o design que contém apenas os recursos de tema e modelos extras, e não os modelos de controle padrão. As áreas de temas são duplicatas daqulo que você veria em generic.xaml.

Quando você usa ferramentas de design de XAML para editar cópias de estilos e modelos, as ferramentas de design extraem seções dos dicionários de recursos de design de XAML e os colocam como cópias locais de elementos do dicionário XAML que fazem parte do seu aplicativo e do projeto.

Para saber mais e obter uma lista dos recursos do sistema e dos recursos específicos de temas que estão disponíveis para um aplicativo da Windows Store em XAML, veja a Referência de recursos de temas XAML.

Comportamento do Windows 8

O Windows 8 não dava suporte à extensão de marcação ThemeResource, ela está disponível a partir do Windows 8.1. Além disso, o Windows 8 não dava suporte à alternância dinâmica dos recursos relacionados ao tema de um aplicativo do Tempo de Execução do Windows. O aplicativo tinha que ser reiniciado para selecionar a alteração de tema dos modelos e estilos XAML. Essa não é uma boa experiência de usuário, portanto, os aplicativos devem ser recompilados e visar o Windows 8.1 de forma que possam usar estilos com usos ThemeResource possam alternar dinamicamente os temas quando o usuário o faz. Os aplicativos que foram compilados para Windows 8 mas estão sendo executados no Windows 8.1 continuam a usar o comportamento do Windows 8.

Referências posteriores em um ResourceDictionary

As referências de recursos XAML em um determinado dicionário de recursos deve fazer referência a um recurso já definido com uma chave, e esse recurso deve aparecer lexicalmente antes da referência de recurso. Referências de encaminhamento não podem ser resolvidas por uma referência de recurso XAML. Por isso, se usar referências de recursos estáticos XAML originadas em outro recurso, crie sua estrutura de dicionário de recursos para que os recursos que são utilizados por outros recursos sejam definidos pela primeira vez em um dicionário de recurso.

Os recursos definidos no nível do aplicativo não podem fazer referência a recursos imediatos. Isso equivale a uma tentativa de referência posterior, pois os recursos do aplicativo são efetivamente processados primeiro (quando o aplicativo é iniciado pela primeira vez, e antes do carregamento de qualquer conteúdo de página de navegação). Entretanto, recursos imediatos podem fazer referência a um recurso de aplicativo e isso pode ser uma técnica bem útil para evitar situações de referência posterior.

Escopo de uso de UserControl

Um elemento UserControl apresenta uma situação especial de comportamento de pesquisa de recursos porque ele tem os conceitos inerentes ao escopo de definição e ao escopo de uso. Um UserControl que faça uma referência de recurso XAML no respectivo escopo de definição deve poder dar suporte à pesquisa desse recurso em sua própria sequência de pesquisa de escopo de definição —, ou seja, ele não pode acessar recursos de aplicativo. Em um escopo de uso do UserControl, uma referência de recurso é tratada como se estivesse na sequência de pesquisa, em direção à respectiva raiz da página de uso (exatamente como qualquer outra referência de recurso feita em um objeto carregado em uma árvore de objetos), e ela pode acessar recursos de aplicativo.

ResourceDictionary e XamlReader.Load

O ResourceDictionary pode ser usado na raiz ou como parte da entrada XAML do método XamlReader.Load. Também será possível incluir referências de recurso XAML nesse XAML se todas essas referências estiverem totalmente autocontidas no XAML enviado para carregamento. XamlReader.Load analisa o XAML em um contexto que não reconhece nenhum outro objeto de ResourceDictionary, nem mesmo Application.Resources. Além disso, não use {ThemeResource} em um XAML enviado para XamlReader.Load.

Usando um ResourceDictionary em código

A maior parte dos cenários de um ResourceDictionary é manipulada exclusivamente no XAML. Você declara o contêiner ResourceDictionary e os recursos contidos nele como um arquivo XAML ou conjunto de nós XAML em um arquivo de definição da interface do usuário. E, em seguida, você usa referências de recurso XAML para solicitar esses recursos de outras partes do XAML. Ainda assim, existem alguns cenários em que o seu aplicativo talvez precise ajustar o conteúdo de um ResourceDictionary usando o código que é executado enquanto o aplicativo está em execução, ou pelo menos consultar o conteúdo de um ResourceDictionary para ver se um recurso já está definido. Essas chamadas de código são feitas em uma instância do ResourceDictionary, portanto, recupere primeiro uma delas — seja um ResourceDictionary imediato, em algum lugar da árvore de objetos por meio da obtenção de FrameworkElement.Resources, seja Application.Current.Resources.

No código de C# ou do Microsoft Visual Basic, você pode referenciar um recurso de um determinado ResourceDictionary usando o indexador (Item). Um ResourceDictionary é um dicionário de cadeias de caracteres inseridas, portanto, o indexador usa a chave de cadeia de caracteres em vez de um número inteiro. No código de extensões de componentes Visual C++ (C++/CX), use Lookup.

Ao usar um código para examinar ou mudar um ResourceDictionary, o comportamento para APIs como Lookup ou Item não percorre de recursos imediatos até recursos de aplicativos, o que é um comportamento do analisador de XAML que só acontece enquanto páginas XAML são carregadas. No tempo de execução, o escopo para chaves é autossuficiente na instância de ResourceDictionary que você está usando no momento. Entretanto, esse escopo não se estende em MergedDictionaries.

Além disso, se você solicitar uma chave não existente no ResourceDictionary, talvez não ocorra nenhum erro; o valor de retorno poderá simplesmente ser fornecido como null. Porém, você ainda poderá receber um erro se tentar usar o null retornado como um valor. O erro seria gerado pelo setter da propriedade, e não pela sua chamada ResourceDictionary. A única maneira de evitar um erro seria se a propriedade aceitasse null como um valor válido. Observe como esse comportamento contrasta com o comportamento de pesquisa XAML no tempo de análise do XAML; uma falha na resolução da chave fornecida pelo XAML no tempo de análise resulta em um erro de análise de XAML, mesmo nos casos em que a propriedade poderia ter aceito null.

Dicionários de recursos mesclados são incluídos no escopo de índice do dicionário de recursos principal que referencia o dicionário mesclado no tempo de execução. Em outras palavras, você pode usar o Item ou a Lookup do dicionário principal para localizar qualquer objeto que na verdade foi definido no dicionário mesclado. Neste caso, o comportamento de pesquisa se parece com o comportamento de pesquisa XAML do tempo de análise: se houver vários objetos nos dicionários mesclados e cada um deles tiver a mesma chave, o objeto do último dicionário adicionado será retornado.

É possível adicionar itens a um ResourceDictionary existente chamando Add (C# ou Visual Basic) ou Insert (C++/CX). Você pode adicionar recursos imediatos ou recursos de aplicativo. Cada uma dessas chamadas de API exige uma chave que atenda à exigência de que cada item em um ResourceDictionary tenha uma chave. Entretanto, os itens adicionados a um ResourceDictionary em tempo de execução não são relevantes para referências de recursos XAML. A pesquisa necessária para referências de recurso XAML acontece quando esse XAML é analisado pela primeira vez quando o aplicativo é carregado (ou um tema alterado é detectado). Os recursos adicionados a coleções no tempo de execução não estavam disponíveis então, e alterar o ResourceDictionary não invalida um recurso já recuperado dele, mesmo que você altere o valor desse recurso.

Também é possível remover itens de um ResourceDictionary em tempo de execução, fazer cópias parcial ou total dos itens ou executar outras operações. A listagem de membros do ResourceDictionary indica quais APIs estão disponíveis. Observe que como o ResourceDictionary tem uma API projetada para dar suporte a suas interfaces de coleção adjacentes, as opções da sua API são diferentes, dependendo de você estar usando C# ou Visual Basic, em vez de C++/CX.

ResourceDictionary e localização

Um ResourceDictionary XAML pode, inicialmente, conter cadeias de caracteres que podem ser localizadas. Se assim for, armazene essas cadeias de caracteres como recursos de projeto, e não em um ResourceDictionary. Retire as cadeias de caracteres do XAML e dê ao elemento proprietário um valor x:Uid. Depois, defina um recurso em um arquivo de recursos. Forneça um nome de recurso na forma XUIDValue.PropertyName e um valor de recurso da cadeia de caracteres a ser localizada. Para saber mais, veja Guia de início rápido: traduzindo recursos de interface de usuário.

Otimização de recursos de carregamento no Windows 8.1

A partir do Windows 8.1, há uma otimização de carregamento de recursos que é habilitada pelo modelo de aplicativo e pelo analisador de XAML do Tempo de Execução do Windows. Para o Windows 8, o analisador de XAML carregava recursos de app.xaml e criava cada um deles como objetos, como parte da inicialização. Isso não era muito eficiente se houvesse grandes dicionários. Além disso, esses recursos incluíam os itens definidos para três temas, e apenas o tema atual é realmente necessário. A partir do Windows 8.1, o analisador de XAML só cria os recursos quando eles são especificamente solicitados por referências de recursos XAML. Essas referências podem vir de outros recursos ou do XML em nível de página à medida que cada página é carregada. O comportamento otimizado do analisador de XAML minimiza o tempo necessário para ler o dicionário em nível de aplicativo no tempo de inicialização e permite que a primeira página do aplicativo seja carregada mais rápido na maioria dos casos. Os recursos necessários por temas inativos apenas serão carregados se esse tema for ativado pelo usuário. Mudar de temas enquanto os aplicativos estão em execução não é algo que os usuários costumam fazer com frequência. Mas, se isso acontecer, qualquer recurso no qual a extensão de marcação ThemeResource tenha sido usada para a solicitação será recalculado com base no tema recém-ativo.

Comportamento do Windows 8

O Windows 8 não tinha as otimizações descritas acima. Por isso, você deve ver algumas diferenças de tempo ao redirecionar seu aplicativo para o Windows 8.1. O aplicativo deve carregar mais rapidamente, entretanto, talvez não seja possível isolar essa melhoria versus outras alterações feitas no código de seu aplicativo como parte do redirecionamento. Alguns dos locais em que você deve ver evidências de mudanças de tempo devidas ao carregamento de recursos otimizado incluem quando os construtores são chamados pelo analisados, para objetos como objetos, conversores ou outras classes personalizadas Application. Os aplicativos que foram compilados para Windows 8 mas estão sendo executados no Windows 8.1 continuam a usar o comportamento do Windows 8.

Pesquisa de recursos personalizada

Em cenários avançados, você pode implementar uma classe que pode ter um comportamento diferente do comportamento de pesquisa de referência de recursos XAML descrito neste tópico. Para fazer isso, implemente a classe CustomXamlResourceLoader para poder acessar esse comportamento usando a extensão de marcação CustomResource para referências de recursos, em vez de usar StaticResource ou ThemeResource. A maioria dos aplicativos não têm cenários que requeiram isso. Para saber mais, veja CustomXamlResourceLoader

Tópicos relacionados

ResourceDictionary
Visão geral do XAML
Extensão de marcação StaticSource
Extensão de marcação ThemeResource
Referência de recursos de temas XAML
Guia de início rápido: traduzindo recursos de interface de usuário
Guia de início rápido: Controles de estilo
Recursos de aplicativos e amostra de localização
Atributo x:Key

 

 

Mostrar:
© 2015 Microsoft