Compartilhar via


Extensão de marcação {ThemeResource}

Fornece um valor para qualquer atributo XAML avaliando uma referência a um recurso, com lógica de sistema adicional que recupera recursos diferentes, dependendo do tema ativo no momento. Semelhante à extensão de marcação {StaticResource}, os recursos são definidos em um ResourceDictionary e um uso de ThemeResource faz referência à chave desse recurso no ResourceDictionary.

Uso do atributo XAML

<object property="{ThemeResource key}" .../>

Valores XAML

Termo Descrição
chave A chave para o recurso solicitado. Essa chave é inicialmente atribuída pelo ResourceDictionary. Uma tecla de recurso pode ser qualquer cadeia de caracteres definida na Gramática XamlName.

Comentários

Um ThemeResource é uma técnica para obter valores para um atributo XAML que são definidos em outro lugar em um dicionário de recursos XAML. A extensão de marcação serve à mesma finalidade básica que a extensão de marcação {StaticResource}. A diferença no comportamento em relação à extensão de marcação {StaticResource} é que uma referência ThemeResource pode usar dinamicamente dicionários diferentes como o local de pesquisa principal, dependendo de qual tema está sendo usado no momento pelo sistema.

Quando o aplicativo é iniciado pela primeira vez, qualquer referência de recurso feita por uma referência ThemeResource é avaliada com base no tema em uso na inicialização. Mas se o usuário alterar posteriormente o tema ativo em tempo de execução, o sistema reavaliará cada referência ThemeResource , recuperará um recurso específico do tema que pode ser diferente e exibirá novamente o aplicativo com novos valores de recurso em todos os locais apropriados na árvore visual. Um StaticResource é determinado no tempo de carregamento XAML/inicialização do aplicativo e não será reavaliado em tempo de execução. (Há outras técnicas, como estados visuais, que recarregam o XAML dinamicamente, mas essas técnicas operam em um nível mais alto do que a avaliação básica de recursos habilitada por {StaticResource}).

ThemeResource usa um argumento, que especifica a chave para o recurso solicitado. Uma chave de recurso é sempre uma cadeia de caracteres no XAML do Tempo de Execução do Windows. Para obter mais informações sobre como a chave de recurso é especificada inicialmente, consulte o atributo x:Key.

Para obter mais informações sobre como definir recursos e usar corretamente um ResourceDictionary, incluindo código de exemplo, consulte Referências de recursos ResourceDictionary e XAML.

Importante Assim como acontece com StaticResource, um ThemeResource não deve tentar fazer uma referência direta a um recurso que é definido lexicalmente mais detalhadamente no arquivo XAML. Não há suporte para a tentativa de fazer isso. Mesmo que a referência direta não falhe, tentar fazer uma acarreta uma penalidade de desempenho. Para obter melhores resultados, ajuste a composição de seus dicionários de recursos para que as referências diretas sejam evitadas.

A tentativa de especificar um ThemeResource para uma chave que não pode ser resolvida gera uma exceção de análise XAML em tempo de execução. As ferramentas de design também podem oferecer avisos ou erros.

Na implementação do processador XAML do Tempo de Execução do Windows, não há representação de classe de suporte para ThemeResource. O equivalente mais próximo no código é usar a API de coleção de um ResourceDictionary, por exemplo, chamando Contains ou *TryGetValue.

ThemeResource é uma extensão de marcação. Extensões de marcação são tipicamente implementadas quando existe um requisito que permite que valores de atributo sejam diferentes de valores literais ou nomes de manipuladores, e o requisito é mais global do que simplesmente colocar conversores de tipo em certos tipos ou propriedades. Todas as extensões de marcação em XAML usam os caracteres "{" e "}" em sua sintaxe de atributo, que é a convenção pela qual um processador XAML reconhece que uma extensão de marcação deve processar o atributo.

Quando e como usar {ThemeResource} em vez de {StaticResource}

As regras pelas quais um ThemeResource é resolvido para um item em um dicionário de recursos geralmente são as mesmas que StaticResource. Uma pesquisa ThemeResource pode se estender para os arquivos ResourceDictionary que são referenciados em uma coleção ThemeDictionaries, mas um StaticResource também pode fazer isso. A diferença é que um ThemeResource pode ser reavaliado em tempo de execução e um StaticResource não.

O conjunto de chaves em cada dicionário de temas deve fornecer o mesmo conjunto de recursos com chaves, independentemente do tema ativo. Se um determinado recurso com chave existir no dicionário de temas HighContrast , outro recurso com esse nome também deverá existir em Light e Default. Se isso não for verdade, a pesquisa de recursos poderá falhar quando o usuário alternar entre os temas e seu aplicativo não tiver a aparência correta. É possível, porém, que um dicionário de temas possa conter recursos com chave que são referenciados apenas dentro do mesmo escopo para fornecer subvalores; eles não precisam ser equivalentes em todos os temas.

Em geral, você deve colocar recursos em dicionários de temas e fazer referências a esses recursos usando ThemeResource somente quando esses valores puderem ser alterados entre temas ou forem suportados por valores que são alterados. Isso é apropriado para esses tipos de recursos:

  • Pincéis, em particular cores para SolidColorBrush. Eles representam cerca de 80% dos usos de ThemeResource nos modelos de controle XAML padrão (generic.xaml).
  • Valores de pixel para bordas, deslocamentos, margem e preenchimento e assim por diante.
  • Propriedades de fonte, como FontFamily ou FontSize.
  • Modelos completos para um número limitado de controles que geralmente são estilizados pelo sistema e usados para apresentação dinâmica, como GridViewItem e ListViewItem.
  • Estilos de exibição de texto (geralmente para alterar a cor da fonte, o plano de fundo e possivelmente o tamanho).

O Tempo de Execução do Windows fornece um conjunto de recursos que se destinam especificamente a ser referenciados por ThemeResource. Todos eles estão listados como parte do arquivo XAML themeresources.xaml, que está disponível na pasta include/winrt/xaml/design como parte do SDK (Software Development Kit) do Windows. Para obter documentação sobre os pincéis de tema e estilos adicionais definidos em themeresources.xaml, consulte Recursos de tema XAML. Os pincéis são documentados em uma tabela que informa qual valor de cor cada pincel tem para cada um dos três temas ativos possíveis.

As definições XAML de estados visuais em um modelo de controle devem usar referências ThemeResource sempre que houver um recurso subjacente que possa ser alterado devido a uma alteração de tema. Uma alteração de tema do sistema normalmente também não causará uma alteração de estado visual. Os recursos precisam usar referências ThemeResource nesse caso para que os valores possam ser reavaliados para o estado visual ainda ativo. Por exemplo, se você tiver um estado visual que altera a cor do pincel de uma parte específica da interface do usuário e uma de suas propriedades, e essa cor do pincel for diferente por tema, deverá usar uma referência ThemeResource para fornecer o valor dessa propriedade no modelo padrão e também qualquer modificação de estado visual nesse modelo padrão.

Os usos de ThemeResource podem ser vistos em uma série de valores dependentes. Por exemplo, um valor Color usado por um SolidColorBrush que também é um recurso com chave pode usar uma referência ThemeResource. Mas todas as propriedades da interface do usuário que usam o recurso SolidColorBrush com chave também usariam uma referência ThemeResource, de modo que é especificamente cada propriedade do tipo Brush que está permitindo uma alteração de valor dinâmico quando o tema é alterado.

Observação{ThemeResource} e a avaliação de recursos em tempo de execução na alternância de tema têm suporte no XAML do Windows 8.1, mas não no XAML para aplicativos direcionados ao Windows 8.

Recursos do sistema

Alguns recursos de tema fazem referência a valores de recursos do sistema como um subvalor subjacente. Um recurso do sistema é um valor de recurso especial que não é encontrado em nenhum dicionário de recursos XAML. Esses valores dependem do comportamento no suporte a XAML do Tempo de Execução do Windows para encaminhar valores do próprio sistema e representá-los em um formato que um recurso XAML possa referenciar. Por exemplo, há um recurso do sistema chamado "SystemColorButtonFaceColor" que representa uma cor RGB. Essa cor vem dos aspectos das cores e temas do sistema que não são apenas específicos do Tempo de Execução do Windows e dos aplicativos do Tempo de Execução do Windows.

Os recursos do sistema geralmente são os valores subjacentes para um tema de alto contraste. O usuário está no controle das opções de cores para seu tema de alto contraste e o usuário faz essas escolhas usando recursos do sistema que também não são específicos para aplicativos do Tempo de Execução do Windows. Ao referenciar os recursos do sistema como referências ThemeResource , o comportamento padrão dos temas de alto contraste para aplicativos do Tempo de Execução do Windows pode usar esses valores específicos do tema que são controlados pelo usuário e expostos pelo sistema. Além disso, as referências agora são marcadas para reavaliação se o sistema detectar uma alteração de tema em tempo de execução.

Um exemplo de uso de {ThemeResource}

Aqui está um exemplo de XAML obtido dos arquivos generic.xaml e themeresources.xaml padrão para ilustrar como usar ThemeResource. Veremos apenas um modelo (o Button padrão) e como duas propriedades são declaradas (Background e Foreground) para responder às alterações de tema.

    <!-- Default style for Windows.UI.Xaml.Controls.Button -->
    <Style TargetType="Button">
        <Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}" />
        <Setter Property="Foreground" Value="{ThemeResource ButtonForegroundThemeBrush}"/>
...

Aqui, as propriedades usam um valor Brush e a referência aos recursos SolidColorBrush nomeados ButtonBackgroundThemeBrush e ButtonForegroundThemeBrush são feitos usando ThemeResource.

Essas mesmas propriedades também são ajustadas por alguns dos estados visuais de um Button. Notavelmente, a cor de fundo muda quando um botão é clicado. Aqui também, as animações Background e Foreground no storyboard do estado visual usam objetos DiscreteObjectKeyFrame e referências a pincéis com ThemeResource como o valor do quadro-chave.

<VisualState x:Name="Pressed">
  <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
        Storyboard.TargetProperty="Background">
      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}" />
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
         Storyboard.TargetProperty="Foreground">
       <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}" />
    </ObjectAnimationUsingKeyFrames>
  </Storyboard>
</VisualState>

Cada um desses pincéis é definido anteriormente em generic.xaml: eles tiveram que ser definidos antes de qualquer modelo que os usasse para evitar referências diretas XAML. Aqui estão essas definições, para o dicionário de temas "Padrão".

    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
...
            <SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="Transparent" />
            <SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="#FFFFFFFF" />
...
            <SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="#FFFFFFFF" />
            <SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="#FF000000" />
...

Em seguida, cada um dos outros dicionários de temas também tem esses pincéis definidos, por exemplo:

        <ResourceDictionary x:Key="HighContrast">
            <!-- High Contrast theme resources -->
...
            <SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
            <SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />

...
            <SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />
            <SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />

Aqui, o valor Color é outra referência ThemeResource a um recurso do sistema. Se você fizer referência a um recurso do sistema e quiser que ele seja alterado em resposta a uma alteração de tema, use ThemeResource para fazer a referência.

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 para um aplicativo do Tempo de Execução do Windows. O aplicativo teve que ser reiniciado para pegar a alteração de tema para os modelos e estilos XAML. Essa não é uma boa experiência do usuário, portanto, os aplicativos são fortemente incentivados a recompilar e direcionar o Windows 8.1 para que possam usar estilos com usos de ThemeResource e alternar dinamicamente os temas quando o usuário o fizer. Os aplicativos que foram compilados para o Windows 8, mas em execução no Windows 8.1, continuam a usar o comportamento do Windows 8.

Suporte a ferramentas de tempo de design para a extensão de marcação {ThemeResource}

O Microsoft Visual Studio 2013 pode incluir possíveis valores de chave nas listas suspensas do Microsoft IntelliSense quando você usa a extensão de marcação {ThemeResource} em uma página XAML. Por exemplo, assim que você digitar "{ThemeResource", qualquer uma das chaves de recurso dos recursos de tema XAML será exibida.

Depois que uma chave de recurso existir como parte de qualquer uso de {ThemeResource} , o recurso Ir para Definição (F12) poderá resolver esse recurso e mostrar o generic.xaml para o tempo de design, em que o recurso de tema é definido. Como os recursos de tema são definidos mais de uma vez (por tema), Ir para Definição leva você à primeira definição encontrada no arquivo, que é a definição de Padrão. Se você quiser as outras definições, poderá pesquisar o nome da chave dentro do arquivo e encontrar as definições dos outros temas.