Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Você pode definir a interface do usuário ou os recursos para seu aplicativo usando XAML. Normalmente, os recursos são definições de algum objeto que você espera usar mais de uma vez. Para fazer referência a um recurso XAML posteriormente, especifique uma chave para um recurso que age como seu nome. Você pode referenciar um recurso em um aplicativo ou em qualquer página XAML dentro dele. Você pode definir seus recursos usando um elemento ResourceDictionary do XAML do Windows Runtime. Em seguida, você pode fazer referência aos seus recursos usando uma extensão de marcação StaticResource ou uma extensão de marcação ThemeResource.
Os elementos XAML que você talvez queira declarar com mais frequência como recursos XAML incluem Style, ControlTemplate, componentes de animação e subclasses de Brush. Aqui, explicamos como definir um ResourceDictionary e recursos chave e como os recursos XAML se relacionam com outros recursos que você define como parte do seu aplicativo ou pacote de aplicativos. Também explicamos os recursos avançados do dicionário de recursos, como MergedDictionaries e ThemeDictionaries.
Observação
Há suporte para C# e C++/WinRT para aplicativos WinUI 3/SDK do Aplicativo Windows e UWP. O C++/CX aplica-se somente à UWP e não tem suporte para WinUI 3.
Pré-requisitos
Uma compreensão sólida da marcação XAML. Recomendamos a leitura da Visão geral de XAML.
Definir e usar recursos XAML
Os recursos XAML são objetos referenciados a partir da marcação mais de uma vez. Os recursos são definidos em um ResourceDictionary, normalmente em um arquivo separado ou na parte superior da página de marcação, como a seguir.
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<x:String x:Key="greeting">Hello world</x:String>
<x:String x:Key="goodbye">Goodbye world</x:String>
</Page.Resources>
<TextBlock Text="{StaticResource greeting}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>
Neste exemplo:
-
<Page.Resources>…</Page.Resources>– Define o dicionário de recursos. -
<x:String>– Define o recurso com a chave "saudação". -
{StaticResource greeting}– pesquisa o recurso com a chave "greeting", que é atribuída à propriedade Text de TextBlock.
Observação
Não confunda os conceitos relacionados ao ResourceDictionary com a ação de build Resource, arquivos de recurso (.resw) ou outros "recursos" que são discutidos no contexto de estruturar o projeto de código que produz o seu pacote de aplicativos.
Os recursos não precisam ser cadeias de caracteres; eles podem ser qualquer objeto compartilhável, como estilos, modelos, pincéis e cores. No entanto, controles, formas e outros FrameworkElementnão são compartilháveis, portanto, não podem ser declarados como recursos reutilizáveis. Para obter mais informações sobre compartilhamento, consulte a seção Recursos XAML devem ser compartilháveis mais adiante neste tópico.
Aqui, um pincel e uma cadeia de caracteres são declarados como recursos e usados por controles em uma página.
<Page
x:Class="SpiderMSDN.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<SolidColorBrush x:Key="myFavoriteColor" Color="green"/>
<x:String x:Key="greeting">Hello world</x:String>
</Page.Resources>
<TextBlock Foreground="{StaticResource myFavoriteColor}" Text="{StaticResource greeting}" VerticalAlignment="Top"/>
<Button Foreground="{StaticResource myFavoriteColor}" Content="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>
Todos os recursos precisam ter uma chave. Normalmente, essa chave é uma cadeia de caracteres definida com x:Key="myString". No entanto, há algumas outras maneiras de especificar uma chave:
- Style e ControlTemplate exigem um TargetType e usarão o TargetType como a chave se x:Key não for especificado. Nesse caso, a chave é o objeto Type real, não uma cadeia de caracteres. (Veja exemplos abaixo)
- Os recursos DataTemplate com um TargetType usarão o TargetType como a chave se x:Key não for especificado. Nesse caso, a chave é o objeto Type real, não uma cadeia de caracteres.
- x:Name pode ser usado em vez de x:Key. No entanto, x:Name também gera um campo code-behind para o recurso. Como resultado, x:Name é menos eficiente que x:Key porque esse campo precisa ser inicializado quando a página é carregada.
A extensão de marcação StaticResource pode recuperar recursos apenas com um nome de cadeia de caracteres (x:Key ou x:Name). No entanto, a estrutura XAML também procura recursos de estilo implícito (aqueles que usam TargetType em vez de x:Key ou x:Name) quando decide qual estilo &modelo usar para um controle que não definiu as propriedades Style e ContentTemplate ou ItemTemplate .
Aqui, Style tem uma chave implícita typeof(Button) e, desde que Button na parte inferior da página não especifique uma propriedade Style, ele procura um estilo com a chave typeof(Button):
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red"/>
</Style>
</Page.Resources>
<Grid>
<!-- This button will have a red background. -->
<Button Content="Button" Height="100" VerticalAlignment="Center" Width="100"/>
</Grid>
</Page>
Para obter mais informações sobre estilos implícitos e como eles funcionam, consulte controles de estilo e modelos de controle.
Pesquisar recursos no código
Você acessa membros do dicionário de recursos como qualquer outro dicionário.
Aviso
Quando você executa uma pesquisa de recursos no código, somente os recursos no Page.Resources dicionário são examinados. Ao contrário da extensão de marcação StaticResource, o código não retorna ao dicionário Application.Resources se os recursos não forem encontrados no primeiro dicionário.
Este exemplo mostra como recuperar o redButtonStyle recurso do dicionário de recursos de uma página:
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style TargetType="Button" x:Key="redButtonStyle">
<Setter Property="Background" Value="red"/>
</Style>
</Page.Resources>
</Page>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Style redButtonStyle = (Style)this.Resources["redButtonStyle"];
}
}
MainPage::MainPage()
{
InitializeComponent();
Windows::UI::Xaml::Style style = Resources().TryLookup(winrt::box_value(L"redButtonStyle")).as<Windows::UI::Xaml::Style>();
}
Para pesquisar recursos em todo o aplicativo a partir do código, use Application.Current.Resources para obter o dicionário de recursos do aplicativo, conforme mostrado aqui.
<Application
x:Class="MSDNSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SpiderMSDN">
<Application.Resources>
<Style TargetType="Button" x:Key="appButtonStyle">
<Setter Property="Background" Value="red"/>
</Style>
</Application.Resources>
</Application>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Style appButtonStyle = (Style)Application.Current.Resources["appButtonStyle"];
}
}
MainPage::MainPage()
{
InitializeComponent();
Windows::UI::Xaml::Style style = Application::Current().Resources()
.TryLookup(winrt::box_value(L"appButtonStyle"))
.as<Windows::UI::Xaml::Style>();
}
Você também pode adicionar um recurso de aplicativo no código.
Há duas coisas para ter em mente ao fazer isso.
- Primeiro, você precisa adicionar os recursos antes que qualquer página tente usar o recurso.
- Em segundo lugar, você não pode adicionar recursos no construtor do aplicativo.
Você poderá evitar ambos os problemas se adicionar o recurso ao método Application.OnLaunched , assim.
// App.xaml.cs
sealed partial class App : Application
{
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = m_window?.Content as Frame; // WinUI 3: Window.Current is always null; store the Window instance in a field
if (rootFrame == null)
{
SolidColorBrush brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 0)); // green
this.Resources["brush"] = brush;
// … Other code that VS generates for you …
}
}
}
// App.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
Frame rootFrame{ nullptr };
auto content = m_window.Content(); // WinUI 3: Window::Current() is always null; store the Window instance in a member field
if (content)
{
rootFrame = content.try_as<Frame>();
}
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
Microsoft::UI::Xaml::Media::SolidColorBrush brush{ Windows::UI::ColorHelper::FromArgb(255, 0, 255, 0) };
Resources().Insert(winrt::box_value(L"brush"), winrt::box_value(brush));
// … Other code that VS generates for you …
Cada FrameworkElement pode ter um ResourceDictionary
FrameworkElement é uma classe base da qual os controles herdam, e ela possui a propriedade Resources. Portanto, você pode adicionar um dicionário de recursos local a qualquer FrameworkElement.
Aqui, a Página e a Borda têm dicionários de recursos e ambos têm um recurso chamado "saudação". O TextBlock chamado “textBlock2” está dentro de Border e, portanto, sua pesquisa de recursos examina primeiro os recursos de Border, depois os recursos de Page e depois os recursos de Application. O TextBlock lerá “Hola mundo”.
Para acessar os recursos desse elemento a partir do código, use a propriedade Resources desse elemento. O acesso aos recursos de um FrameworkElement no código, em vez de XAML, examinará apenas esse dicionário, não os dicionários do elemento pai.
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<x:String x:Key="greeting">Hello world</x:String>
</Page.Resources>
<StackPanel>
<!-- Displays "Hello world" -->
<TextBlock x:Name="textBlock1" Text="{StaticResource greeting}"/>
<Border x:Name="border">
<Border.Resources>
<x:String x:Key="greeting">Hola mundo</x:String>
</Border.Resources>
<!-- Displays "Hola mundo" -->
<TextBlock x:Name="textBlock2" Text="{StaticResource greeting}"/>
</Border>
<!-- Displays "Hola mundo", set in code. -->
<TextBlock x:Name="textBlock3"/>
</StackPanel>
</Page>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
textBlock3.Text = (string)border.Resources["greeting"];
}
}
MainPage::MainPage()
{
InitializeComponent();
textBlock3().Text(unbox_value<hstring>(border().Resources().TryLookup(winrt::box_value(L"greeting"))));
}
Dicionários de recursos mesclados
Um dicionário de recursos mesclado combina um dicionário de recursos em outro, geralmente em outro arquivo.
Dica Você pode criar um arquivo de dicionário de recursos no Microsoft Visual Studio usando a opção Adicionar > Novo Item... > Dicionário de Recursos no menu Projeto.
Aqui, você define um dicionário de recursos em um arquivo XAML separado chamado Dictionary1.xaml.
<!-- Dictionary1.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MSDNSample">
<SolidColorBrush x:Key="brush" Color="Red"/>
</ResourceDictionary>
Para usar esse dicionário, mescla-o com o dicionário da página:
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
<x:String x:Key="greeting">Hello world</x:String>
</ResourceDictionary>
</Page.Resources>
<TextBlock Foreground="{StaticResource brush}" Text="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>
Veja o que acontece neste exemplo. Em <Page.Resources>, você declara <ResourceDictionary>. A estrutura XAML cria implicitamente um dicionário de recursos para você quando você adiciona recursos a <Page.Resources>; no entanto, neste caso, você não quer apenas qualquer dicionário de recursos, você quer um que contenha dicionários mesclados.
Então você declara <ResourceDictionary>, em seguida, adicionar coisas à sua coleção <ResourceDictionary.MergedDictionaries>. Cada uma dessas entradas assume a forma <ResourceDictionary Source="Dictionary1.xaml"/>. Para adicionar mais de um dicionário, basta adicionar uma <ResourceDictionary Source="Dictionary2.xaml"/> entrada após a primeira entrada.
Depois <ResourceDictionary.MergedDictionaries>…</ResourceDictionary.MergedDictionaries>, opcionalmente, você pode colocar recursos adicionais em seu dicionário principal. Você usa recursos de um dicionário mesclado como um dicionário normal. No exemplo acima, {StaticResource brush} localiza o recurso no dicionário filho/mesclado (Dictionary1.xaml), enquanto {StaticResource greeting} localiza seu recurso no dicionário de páginas principal.
Na sequência de pesquisa de recursos, um dicionário MergedDictionaries só é verificado após a verificação de todos os recursos com chave do ResourceDictionary. Depois de consultar esse nível, a pesquisa atinge os dicionários mesclados e cada item em MergedDictionaries é verificado. Se existirem vários dicionários mesclados, esses dicionários serão verificados no inverso da ordem em que são declarados na propriedade MergedDictionaries . No exemplo a seguir, se Dictionary2.xaml e Dictionary1.xaml declararem a mesma chave, a chave de Dictionary2.xaml será usada primeiro porque é a última no conjunto MergedDictionaries .
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
<ResourceDictionary Source="Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<TextBlock Foreground="{StaticResource brush}" Text="greetings!" VerticalAlignment="Center"/>
</Page>
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 cor de pincel específica no último dicionário de recursos mesclado na sequência, usando um dicionário de recursos que sincroniza com os dados de preferência do usuário e de estado do aplicativo. No entanto, se não houver nenhuma preferência de usuário, você poderá definir essa mesma cadeia de caracteres de chave para um recurso ResourceDictionary no arquivo MergedDictionaries inicial e isso pode servir como o valor de fallback. Lembre-se de que qualquer valor fornecido em um dicionário de recursos primário é sempre verificado antes que os dicionários mesclados sejam verificados, portanto, se você quiser usar a técnica de fallback, não defina esse recurso em um dicionário de recursos primário.
Recursos de tema e dicionários de temas
Um ThemeResource é semelhante a um StaticResource, mas a pesquisa de recursos é reavaliada quando o tema é alterado.
Neste exemplo, você define o primeiro plano de um TextBlock como um valor do tema atual.
<TextBlock Text="hello world" Foreground="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" VerticalAlignment="Center"/>
Um dicionário de temas é um tipo especial de dicionário mesclado que contém os recursos que variam com o tema que um usuário está usando atualmente em seu dispositivo. Por exemplo, o tema "claro" pode usar um pincel de cor branca, enquanto o tema "escuro" pode usar um pincel de cor escura. O pincel altera o recurso para o qual ele resolve, mas, caso contrário, a composição de um controle que usa o pincel como um recurso pode ser a mesma. Para reproduzir o comportamento de alternância de temas 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.
Cada elemento ResourceDictionary dentro de ThemeDictionaries deve ter um valor x:Key. O valor é uma cadeia de caracteres que nomeia o tema relevante, por exemplo, "Padrão", "Escuro", "Claro" ou "HighContrast". Normalmente, Dictionary1 e Dictionary2 definirão recursos que têm os mesmos nomes, mas valores diferentes.
Aqui, você usa texto vermelho para o tema claro e texto azul para o tema escuro.
<!-- Dictionary1.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MSDNSample">
<SolidColorBrush x:Key="brush" Color="Red"/>
</ResourceDictionary>
<!-- Dictionary2.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MSDNSample">
<SolidColorBrush x:Key="brush" Color="blue"/>
</ResourceDictionary>
Neste exemplo, você define o primeiro plano de um TextBlock como um valor do tema atual.
<Page
x:Class="MSDNSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" x:Key="Light"/>
<ResourceDictionary Source="Dictionary2.xaml" x:Key="Dark"/>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
<TextBlock Foreground="{StaticResource brush}" Text="hello world" VerticalAlignment="Center"/>
</Page>
Para dicionários de temas, o dicionário ativo a ser usado para pesquisa de recursos muda dinamicamente toda vez que a extensão de marcação ThemeResource é utilizada para fazer a referência, e o sistema detecta uma alteração de tema. O comportamento de pesquisa realizado pelo sistema baseia-se no mapeamento do tema ativo para a chave x:Key de um dicionário de temas específico.
Pode ser útil examinar a forma como os dicionários de temas são estruturados nos recursos de design XAML padrão, que são paralelos aos modelos que o Windows Runtime usa por padrão para seus controles. Abra os arquivos XAML em \(Arquivos de Programas)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<versão do SDK>\Generic usando um editor de texto ou seu IDE. 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 chave desse tipo é então referenciada por elementos de composição nos vários elementos chave que estão fora dos dicionários de temas e definidos posteriormente no XAML. Há também um arquivo themeresources.xaml separado para design que contém apenas os recursos de tema e modelos extras, não os modelos de controle padrão. As áreas de tema são duplicatas do que você veria em generic.xaml.
Quando você usa ferramentas de design XAML para editar cópias de estilos e modelos, as ferramentas de design extraem seções dos dicionários de recursos de design XAML e as colocam como cópias locais de elementos de dicionário XAML que fazem parte do seu aplicativo e projeto.
Para obter mais informações e para obter uma lista dos recursos específicos do tema e do sistema que estão disponíveis para seu aplicativo, consulte os recursos de tema XAML.
Comportamento de pesquisa para referências de recursos XAML
Comportamento de busca é o termo que descreve como o sistema XAML de recursos tenta encontrar um recurso XAML. A pesquisa ocorre quando uma chave é referenciada como uma referência de recurso XAML de algum lugar no XAML do aplicativo. Primeiro, o sistema de recursos tem um comportamento previsível para onde 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 todos os locais e escopos em que um recurso XAML poderia possivelmente ser definido por um aplicativo ou pelo sistema. Se todas as possíveis tentativas de pesquisa de recursos falharem, um erro geralmente resultará. Geralmente, é 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 nesse local, esse ResourceDictionary será verificado para obter um item que tenha a chave solicitada. Esse primeiro nível de pesquisa raramente é relevante porque você geralmente não define e faz referência a um recurso no mesmo objeto. Na verdade, uma propriedade Resources muitas vezes não existe aqui. Você pode fazer referências de recurso XAML de praticamente qualquer lugar no XAML; você não está limitado às propriedades das subclasses FrameworkElement .
A sequência de pesquisa, em seguida, verifica o próximo objeto pai na árvore de objetos de runtime 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 para o local onde a referência foi feita. Caso contrário, o comportamento de pesquisa avança para o próximo nível pai em direção à raiz da árvore de objetos. A pesquisa continua recursivamente para cima até que o elemento raiz do XAML seja atingido, esgotando a pesquisa de todos os possíveis locais de recursos imediatos.
Observação
É uma prática comum definir todos os recursos imediatos no nível raiz de uma página, tanto para aproveitar esse comportamento de pesquisa de recursos quanto 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 todos os recursos específicos do aplicativo referenciados por várias páginas na estrutura de navegação do aplicativo.
Importante
A ordem dos recursos adicionados a um ResourceDictionary afeta a ordem na qual eles são aplicados. O dicionário XamlControlsResources substitui várias chaves de recurso padrão. Portanto, deve ser adicionado a Application.Resources primeiro, para que não substitua outros estilos ou recursos personalizados no aplicativo.
Os modelos de controle têm outro local possível na pesquisa de referência: dicionários de temas. Um dicionário de temas é um único arquivo XAML que tem um elemento ResourceDictionary como raiz. O dicionário de temas pode ser um dicionário mesclado de Application.Resources. O dicionário de tema também pode ser o dicionário de tema específico de controle para um controle personalizado de modelo.
Finalmente, há uma pesquisa de recursos em relação aos recursos da plataforma. Os recursos da 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 que você usa para interface do usuário em um aplicativo do Windows Runtime. Os recursos da plataforma também incluem um conjunto de recursos nomeados relacionados à aparência e temas do sistema inteiro. 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 fornece uma definição de Cor para corresponder a cor do texto do aplicativo à cor de texto de uma janela do sistema proveniente do sistema operacional e das preferências do usuário. Outros estilos XAML para seu aplicativo podem se referir a esse estilo ou seu código pode obter um valor de pesquisa de recurso (e convertê-lo em Cor no caso de exemplo).
Para obter mais informações e para obter uma lista dos recursos específicos do tema e do sistema que estão disponíveis para um aplicativo do Windows que usa XAML, consulte os recursos de tema XAML.
Se a chave solicitada ainda não for encontrada em nenhum desses 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 em tempo de execução que não é detectada por uma ação de compilação de marcação XAML ou por um ambiente de design XAML.
Devido ao comportamento de pesquisa em camadas para dicionários de recursos, você pode definir deliberadamente vários itens de recurso que cada um tem o mesmo valor de cadeia de caracteres que a chave, desde que cada recurso seja definido em um nível diferente. Em outras palavras, embora as chaves precisem ser exclusivas em qualquer ResourceDictionary, o requisito de exclusividade não se estende à sequência de comportamento de pesquisa como um todo. Durante a pesquisa, somente o primeiro objeto desse tipo recuperado com êxito é usado para a referência de recurso XAML e, em seguida, a pesquisa é interrompida. Você pode usar este comportamento para solicitar o mesmo recurso XAML por chave em várias posições dentro do XAML do seu aplicativo, mas receber recursos diferentes, dependendo do escopo de onde a referência ao recurso XAML foi realizada e de como essa pesquisa específica se comporta.
Encaminhar referências em um ResourceDictionary
As referências de recurso XAML em um dicionário de recursos específico devem fazer referência a um recurso que já foi definido com uma chave e esse recurso deve aparecer lexicamente antes da referência de recurso. Referências avançadas não podem ser resolvidas por uma referência de recurso XAML. Por esse motivo, se você usar referências de recurso XAML de dentro de outro recurso, deverá criar sua estrutura de dicionário de recursos para que os recursos usados por outros recursos sejam definidos primeiro em um dicionário de recursos.
Os recursos definidos no nível do aplicativo não podem fazer referências a recursos imediatos. Isso equivale a tentar uma referência antecipada, pois os recursos do aplicativo são processados inicialmente (quando o aplicativo é iniciado pela primeira vez e antes de qualquer conteúdo de página de navegação ser carregado). No entanto, qualquer recurso disponível imediatamente pode fazer uma referência a um recurso de aplicativo, e isso pode ser uma técnica útil para evitar situações de referência antecipada.
Os recursos XAML devem ser compartilháveis
Para que um objeto exista em um ResourceDictionary, esse objeto deve ser compartilhável.
Ser compartilhável é necessário porque, quando a árvore de objetos de um aplicativo é construída e usada em tempo de execução, os objetos não podem existir em vários locais na árvore. Internamente, o sistema de recursos cria cópias de valores de recurso a serem usadas no grafo de objeto do aplicativo quando cada recurso XAML é solicitado.
Um ResourceDictionary e o XAML do Windows Runtime de modo geral dão suporte a esses objetos para uso compartilhado.
- Estilos e modelos (Style e classes derivadas de FrameworkTemplate)
- Pincéis e cores (classes derivadas de valores Brush e Color)
- Tipos de animação, incluindo Storyboard
- Transformações (classes derivadas de GeneralTransform)
- Matrix e Matrix3D
- Valores Point
- Determinadas estruturas relacionadas à interface do usuário, como Thickness e CornerRadius
- Tipos de dados XAML intrínsecos
Você também pode usar tipos personalizados como um recurso compartilhável se seguir os padrões de implementação necessários. Você define essas classes em seu código de backup (ou em componentes de runtime que você inclui) e, em seguida, instancia essas classes em XAML como um recurso. Exemplos são fontes de dados de objeto e implementações IValueConverter para associação de dados.
Os tipos personalizados devem ter um construtor padrão, pois é 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, pois um UIElement nunca pode ser compartilhável (ele sempre se destina a representar exatamente um elemento de interface do usuário que existe em uma posição no grafo de objeto do seu aplicativo de runtime).
Escopo de uso do UserControl
Um elemento UserControl tem uma situação especial para o comportamento de pesquisa de recursos porque tem os conceitos inerentes de um escopo de definição e um escopo de uso. Um UserControl que faz uma referência a um recurso XAML de seu escopo de definição deve conseguir buscar esse recurso dentro de seu próprio escopo de definição—ou seja, não pode acessar recursos do aplicativo. No escopo de uso de um UserControl, uma referência de recurso é tratada como estando dentro da sequência de pesquisa em direção à raiz da página de uso (assim como qualquer outra referência de recurso feita a partir de um objeto em uma árvore de objetos carregada) e pode acessar recursos do aplicativo.
ResourceDictionary e XamlReader.Load
O ResourceDictionary pode ser usado na raiz ou como parte da entrada XAML do método XamlReader.Load. Você também pode incluir referências a recursos XAML nesse XAML, desde que todas essas referências sejam totalmente autossuficientes no XAML enviado para carregamento.
XamlReader.Load analisa o XAML em um contexto que não está ciente de nenhum outro objeto ResourceDictionary, nem mesmo de Application.Resources. Além disso, não use {ThemeResource} de dentro do XAML enviado para XamlReader.Load.
Usando um ResourceDictionary a partir do código
A maioria dos cenários para um ResourceDictionary é tratada exclusivamente em XAML. Você declara o ResourceDictionary como um contêiner e os recursos que nele estão como um arquivo XAML ou um conjunto de nós XAML em um arquivo de definição da interface do usuário. Em seguida, você usa referências de recurso XAML para solicitar esses recursos de outras partes do XAML. Ainda assim, há certos cenários em que seu aplicativo pode querer ajustar o conteúdo de um ResourceDictionary usando o código que é executado enquanto o aplicativo está em execução ou pelo menos para 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 de ResourceDictionary, portanto, recupere primeiro uma delas seja um ResourceDictionary imediato, em algum lugar da árvore de objetos obtendo FrameworkElement.Resources ou Application.Current.Resources.
Em C#, você pode referenciar um recurso em um determinado ResourceDictionary usando o indexador (Item). Um ResourceDictionary é um dicionário com chave de cadeia de caracteres, portanto, o indexador usa a chave de cadeia de caracteres em vez de um índice 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 passa de recursos imediatos para recursos do aplicativo, o que é um comportamento do analisador de XAML que só acontece enquanto páginas XAML são carregadas. Em tempo de execução, o escopo das chaves é autossuficiente para a instância ResourceDictionary que você está usando no momento. No entanto, esse escopo se estende até MergedDictionaries.
Além disso, se você solicitar uma chave que não existe no ResourceDictionary, talvez não haja um erro; o valor retornado pode simplesmente ser fornecido como nulo. No entanto, você ainda poderá receber um erro se tentar usar o valor nulo retornado como um valor. O erro viria do setter da propriedade, não da sua chamada ResourceDictionary. A única maneira de evitar um erro é se a propriedade aceitar null como um valor válido. Observe como esse comportamento contrasta com o comportamento de pesquisa XAML no tempo de análise XAML. Uma falha em resolver a chave fornecida do XAML em tempo de análise resulta em um erro de análise XAML, mesmo nos casos em que a propriedade poderia ter aceitado null.
Os dicionários de recursos mesclados são incluídos no escopo de índice do dicionário de recursos primário que faz referência ao dicionário mesclado em tempo de execução. Em outras palavras, você pode usar Item ou Lookup do dicionário principal para localizar qualquer objeto que na verdade foi definido no dicionário mesclado. Nesse caso, o comportamento de pesquisa se assemelha ao comportamento de pesquisa XAML em tempo de análise: se houver vários objetos em dicionários mesclados que cada um tem a mesma chave, o objeto do dicionário adicionado pela última vez será retornado.
Você tem permissão para adicionar itens a um ResourceDictionary existente chamando Add or Insert (C++/CX). Você pode adicionar os itens a recursos imediatos ou recursos de aplicativo. Qualquer uma dessas chamadas à API requer uma chave, o que atende ao requisito de que cada item em um ResourceDictionary deve ter uma chave. No entanto, os itens que você adiciona a um ResourceDictionary em tempo de execução não são relevantes para referências de recurso XAML. A pesquisa necessária para referências de recurso XAML ocorre quando esse XAML é analisado pela primeira vez à medida que o aplicativo é carregado (ou uma alteração de tema é detectada). Os recursos adicionados às coleções em tempo de execução não estavam disponíveis, e alterar o ResourceDictionary não invalida um recurso já recuperado dele mesmo se você alterar o valor desse recurso.
Você também pode remover itens de um ResourceDictionary em tempo de execução, fazer cópias de alguns ou todos os itens ou outras operações. A listagem de membros para 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 subjacentes, suas opções de API diferem dependendo se você estiver usando C# versus C++/CX.
ResourceDictionary e localização
Um ResourceDictionary XAML pode, inicialmente, conter cadeias de caracteres que podem ser localizadas. Em caso afirmativo, armazene essas cadeias de caracteres como recursos de projeto em vez de em um ResourceDictionary. Retire as cadeias de caracteres do XAML e, em vez disso, dê ao elemento proprietário um valor de diretiva x:Uid. Em seguida, defina um recurso em um arquivo de recursos. Forneça um nome de recurso no formato XUIDValue.PropertyName e um valor de recurso da cadeia de caracteres que deve ser localizada.
Pesquisa de recursos personalizados
Para cenários avançados, você pode implementar uma classe que pode ter um comportamento diferente do comportamento de pesquisa de referência de recurso XAML descrito neste tópico. Para fazer isso, você implementa a classe CustomXamlResourceLoadere pode então 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 terá cenários que exijam isso. Para obter mais informações, consulte CustomXamlResourceLoader.
Tópicos relacionados
Windows developer