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.
Um recurso é um objeto que pode ser reutilizado em locais diferentes em seu aplicativo. Exemplos de recursos incluem pincéis e estilos. Esta visão geral descreve como usar recursos em XAML (Extensible Application Markup Language). Você também pode criar e acessar recursos usando o código.
Observação
Os recursos XAML descritos neste artigo são diferentes dos recursos do aplicativo, que geralmente são arquivos adicionados a um aplicativo, como conteúdo, dados ou arquivos inseridos.
Usar recursos em XAML
O exemplo a seguir define um SolidColorBrush como um recurso no elemento raiz de uma página. Em seguida, o exemplo faz referência ao recurso e o usa para definir propriedades de vários elementos filho, incluindo um Ellipse, um TextBlocke um Button.
<Window x:Class="resources.ResExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ResExample" Height="400" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="#05E0E9"/>
<Style TargetType="Border">
<Setter Property="Background" Value="#4E1A3D" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="#4E1A3D"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="TitleText">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="#4E87D4"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="Margin" Value="0,10,10,10"/>
</Style>
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="Foreground" Value="{StaticResource MyBrush}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="0,3,10,0"/>
</Style>
</Window.Resources>
<Border>
<StackPanel>
<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
<TextBlock Style="{StaticResource Label}">Label</TextBlock>
<TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
<Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
<Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
</StackPanel>
</Border>
</Window>
Cada elemento de nível de estrutura (FrameworkElement ou FrameworkContentElement) tem uma Resources propriedade, que é um ResourceDictionary tipo que contém recursos definidos. Você pode definir recursos em qualquer elemento, como um Button. No entanto, os recursos geralmente são definidos no elemento raiz, que está Window no exemplo.
Cada recurso em um dicionário de recursos deve ter uma chave exclusiva. Ao definir recursos na marcação, você atribui a chave exclusiva por meio da Diretiva x:Key. Normalmente, a chave é uma cadeia de caracteres; no entanto, você também pode defini-lo para outros tipos de objeto usando as extensões de marcação apropriadas. Chaves não textuais para recursos são usadas por determinadas áreas de funcionalidades no WPF, especialmente para estilos, recursos de componentes e formatação de dados.
Você pode usar um recurso definido com a sintaxe de extensão de marcação de recurso que especifica o nome da chave do recurso. Por exemplo, use o recurso como o valor de uma propriedade em outro elemento.
<Button Background="{StaticResource MyBrush}"/>
<Ellipse Fill="{StaticResource MyBrush}"/>
No exemplo anterior, quando o carregador XAML processa o valor {StaticResource MyBrush}
para a propriedade Background em Button, a lógica de busca de recursos primeiro verifica o dicionário de recursos para o elemento Button
. Se Button
não tiver uma definição da chave MyBrush
de recurso (nesse exemplo ela não tem; sua coleção de recursos está vazia), a pesquisa em seguida verifica o elemento pai de Button
. Se o recurso não estiver definido no pai, ele continuará verificando a árvore lógica do objeto para cima até que ele seja encontrado.
Se você definir recursos no elemento raiz, todos os elementos na árvore lógica, como o Window ou Page, poderão acessá-lo. E você pode reutilizar o mesmo recurso para definir o valor de qualquer propriedade que aceite o mesmo tipo que o recurso representa. No exemplo anterior, o mesmo MyBrush
recurso define duas propriedades diferentes: Button.Background e Ellipse.Fill.
Recursos estáticos e dinâmicos
Um recurso pode ser referenciado como estático ou dinâmico. As referências são criadas usando a Extensão de Marcação StaticResource ou a Extensão de Marcação DynamicResource. Uma extensão de marcação é um recurso XAML que permite especificar uma referência de objeto fazendo com que a extensão de marcação processe a cadeia de caracteres de atributo e retorne o objeto a um carregador XAML. Para obter mais informações sobre o comportamento da extensão de marcação, consulte Extensões de Marcação e XAML do WPF.
Quando você usa uma extensão de marcação, normalmente fornece um ou mais parâmetros no formato de cadeia de caracteres que são processados por essa extensão de marcação específica. A Extensão de Marcação StaticResource processa uma chave pesquisando o valor dessa chave em todos os dicionários de recursos disponíveis. O processamento ocorre durante a carga, que é quando o processo de carregamento precisa atribuir o valor da propriedade. Em vez disso, a Extensão de Marcação DynamicResource processa uma chave criando uma expressão e essa expressão permanece não avaliada até que o aplicativo seja executado, momento em que a expressão é avaliada para fornecer um valor.
Quando você faz referência a um recurso, as seguintes considerações podem influenciar se você usa uma referência de recurso estático ou uma referência de recurso dinâmico:
Ao determinar o design geral de como você cria os recursos para seu aplicativo (por página, no aplicativo, em XAML flexível ou em um assembly somente de recursos), considere o seguinte:
A funcionalidade do aplicativo. A atualização de recursos em tempo real faz parte dos requisitos do aplicativo?
O respectivo comportamento de pesquisa desse tipo de referência de recurso.
A propriedade ou o tipo de recurso específico e o comportamento nativo desses tipos.
Recursos estáticos
As referências de recursos estáticos funcionam melhor para as seguintes circunstâncias:
O design do aplicativo concentra a maioria de seus recursos em dicionários de recursos no nível da página ou do aplicativo.
As referências de recursos estáticos não são reavaliadas com base em comportamentos de runtime, como recarregar uma página. Portanto, pode haver algum benefício de desempenho para evitar um grande número de referências de recursos dinâmicos quando elas não forem necessárias com base no design do recurso e do aplicativo.
Você está definindo o valor de uma propriedade que não está em um DependencyObject ou em um Freezable.
Você está criando um dicionário de recursos compilado em uma DLL compartilhada entre aplicativos.
Você está criando um tema para um controle personalizado e está definindo recursos que são usados dentro dos temas.
Para esse caso, normalmente você não deseja o comportamento de pesquisa de referência de recurso dinâmico. Em vez disso, use o comportamento de referência de recurso estático para que a pesquisa seja previsível e independente do tema. Com uma referência dinâmica de recurso, até mesmo uma referência dentro de um tema é deixada não avaliada até o momento da execução. E, há uma chance de que, quando o tema for aplicado, algum elemento local redefina uma chave que seu tema está tentando referenciar, e o elemento local aparecerá antes do próprio tema na busca. Se isso acontecer, seu tema não se comportará conforme o esperado.
Você está usando recursos para definir um grande número de propriedades de dependência. As propriedades de dependência possuem o cache de valor efetivo habilitado pelo sistema de propriedades. Portanto, se você fornecer um valor que possa ser avaliado no momento do carregamento, a propriedade de dependência não precisará verificar uma expressão reavaliada e poderá retornar o último valor efetivo. Essa técnica pode ser um benefício de desempenho.
Você deseja alterar o recurso subjacente para todos os consumidores ou deseja manter instâncias graváveis separadas para cada consumidor usando o atributo x:Shared.
Comportamento de pesquisa de recursos estáticos
O seguinte descreve o processo de pesquisa que ocorre automaticamente quando um recurso estático é referenciado por uma propriedade ou elemento:
O processo de pesquisa verifica a chave solicitada dentro do dicionário de recursos definido pelo elemento que define a propriedade.
Em seguida, o processo de pesquisa percorre a árvore lógica para cima até o elemento pai e seu dicionário de recursos. Esse processo continua até que o elemento raiz seja atingido.
Os recursos do aplicativo são verificados. Os recursos do aplicativo são aqueles presentes no dicionário de recursos que são definidos pelo objeto Application para o seu aplicativo WPF.
Referências de recursos estáticos de dentro de um dicionário de recursos devem fazer referência a um recurso que já foi definido lexicamente antes da referência de recurso. Referências avançadas não podem ser resolvidas por uma referência de recurso estático. Por esse motivo, crie sua estrutura de dicionário de recursos de modo que os recursos sejam definidos no início ou próximo do início de cada dicionário de recursos respectivo.
A pesquisa de recursos estáticos pode se estender em temas ou em recursos do sistema, mas essa pesquisa só tem suporte porque o carregador XAML adia a solicitação. O adiamento é necessário para que o tema do runtime no momento em que a página é carregada se aplique corretamente ao aplicativo. No entanto, as referências de recursos estáticos a chaves que são conhecidas por existirem apenas em temas ou como recursos do sistema não são recomendadas, pois essas referências não serão reavaliadas se o tema for alterado pelo usuário em tempo real. Uma referência de recurso dinâmico é mais confiável quando você solicita recursos de tema ou sistema. A exceção é quando um elemento de tema em si solicita outro recurso. Essas referências devem ser referências de recursos estáticos, pelos motivos mencionados anteriormente.
O comportamento de exceção se uma referência de recurso estático não for encontrada varia. Se o recurso tiver sido adiado, a exceção ocorrerá em runtime. Se o recurso não tiver sido adiado, a exceção ocorrerá no momento da carga.
Recursos dinâmicos
Os recursos dinâmicos funcionam melhor quando:
O valor do recurso, incluindo recursos do sistema ou recursos que, de outra forma, são configuráveis pelo usuário, depende de condições que não são conhecidas até o runtime. Por exemplo, você pode criar valores setter que se referem às propriedades do sistema, conforme exposto por SystemColors, SystemFontsou SystemParameters. Esses valores são realmente dinâmicos porque, em última análise, vêm do ambiente de runtime do usuário e do sistema operacional. Você também pode ter temas no nível do aplicativo que podem ser alterados, em que o acesso a recursos no nível da página também deve capturar a alteração.
Você está criando ou referenciando estilos de tema para um controle personalizado.
Você pretende ajustar os conteúdos de um ResourceDictionary ao longo do tempo de vida do aplicativo.
Você tem uma estrutura de recursos complicada que possui interdependências, onde pode ser necessária uma referência futura. Referências de recursos estáticos não dão suporte a referências de encaminhamento, mas referências de recursos dinâmicos dão suporte a elas porque o recurso não precisa ser avaliado até o runtime e, portanto, as referências de encaminhamento não são um conceito relevante.
Você está fazendo referência a um recurso grande da perspectiva de um conjunto de compilação ou de trabalho, e o recurso pode não ser usado imediatamente quando a página é carregada. As referências de recursos estáticos sempre são carregadas de XAML quando a página é carregada. No entanto, uma referência de recurso dinâmico não é carregada até que seja usada.
Você está criando um estilo em que os valores de setter podem vir de outros valores que são influenciados por temas ou outras configurações de usuário.
Você está aplicando recursos a elementos que podem ser reparenciados na árvore lógica durante o tempo de vida do aplicativo. Alterar o pai também potencialmente altera o escopo de pesquisa de recursos, portanto, se você quiser que o recurso de um elemento reparentado seja reavaliado com base no novo escopo, sempre use uma referência de recurso dinâmico.
Comportamento de pesquisa de recursos dinâmicos
O comportamento de pesquisa de recursos para uma referência de recurso dinâmico paraleliza o comportamento de pesquisa em seu código se você chamar FindResource ou SetResourceReference:
A pesquisa verifica a chave solicitada dentro do dicionário de recursos definido pelo elemento que define a propriedade:
Se o elemento definir a propriedade Style, o elemento System.Windows.FrameworkElement.Style terá seu dicionário Resources verificado.
Se o elemento definir uma Template propriedade, o System.Windows.FrameworkTemplate.Resources dicionário do elemento será verificado.
A pesquisa percorre a árvore lógica para cima até o elemento pai e seu dicionário de recursos. Esse processo continua até que o elemento raiz seja atingido.
Os recursos do aplicativo são verificados. Os recursos do aplicativo são aqueles recursos no dicionário de recursos que são definidos pelo objeto Application para o seu aplicativo WPF.
O dicionário de recursos do tema é verificado para o tema atualmente ativo. Se o tema for alterado em runtime, o valor será reavaliado.
Os recursos do sistema são verificados.
O comportamento da exceção (se houver) varia:
Se um recurso foi solicitado por uma FindResource chamada e não foi encontrado, uma exceção é gerada.
Se um recurso foi solicitado por uma TryFindResource chamada e não foi encontrado, nenhuma exceção é gerada e o valor retornado é
null
. Se a propriedade que está sendo definida não aceitarnull
, ainda será possível que uma exceção mais profunda seja gerada, dependendo da propriedade individual que está sendo definida.Se um recurso foi solicitado por uma referência de recurso dinâmico em XAML e não foi encontrado, o comportamento depende do sistema de propriedades geral. O comportamento geral é como se nenhuma operação de configuração de propriedade tivesse ocorrido no nível em que o recurso existe. Por exemplo, se você tentar definir a tela de fundo em um elemento de botão individual usando um recurso que não pôde ser avaliado, nenhum valor definirá os resultados, mas o valor efetivo ainda poderá vir de outros participantes no sistema de propriedades e precedência de valor. Por exemplo, o valor da tela de fundo ainda pode vir de um estilo de botão definido localmente ou do estilo do tema. Para propriedades que não são definidas por estilos de tema, o valor efetivo após uma avaliação de recurso com falha pode vir do valor padrão nos metadados da propriedade.
Restrições
As referências de recursos dinâmicos têm algumas restrições notáveis. Pelo menos uma das seguintes condições deve ser verdadeira:
A propriedade que está sendo definida deve ser uma propriedade em um FrameworkElement ou FrameworkContentElement. Essa propriedade deve ser suportada por um DependencyProperty.
A referência é para um valor dentro de um
StyleSetter
.A propriedade que está sendo definida deve ser uma propriedade de um Freezable, fornecida como um valor de propriedade de FrameworkElement ou FrameworkContentElement, ou como um valor de Setter.
Como a propriedade que está sendo definida deve ser uma propriedade DependencyProperty ou uma propriedade Freezable, a maioria das alterações de propriedade pode se propagar para a interface do usuário porque uma alteração de propriedade (o valor alterado do recurso dinâmico) é reconhecida pelo sistema de propriedades. A maioria dos controles inclui a lógica que forçará um novo layout de um controle se uma DependencyProperty for alterada e essa propriedade puder afetar o layout. No entanto, nem todas as propriedades que têm uma Extensão de Marcação DynamicResource como seu valor são garantidas para fornecer atualizações em tempo real na interface do usuário. Essa funcionalidade ainda pode variar dependendo da propriedade e dependendo do tipo que possui a propriedade ou até mesmo da estrutura lógica do seu aplicativo.
Estilos, DataTemplates e chaves implícitas
Embora todos os itens em um ResourceDictionary devam ter uma chave, isso não significa que todos os recursos devem ter um x:Key
explícito. Vários tipos de objeto dão suporte a uma chave implícita quando definida como um recurso, em que o valor da chave está vinculado ao valor de outra propriedade. Esse tipo de chave é conhecido como uma chave implícita e um x:Key
atributo é uma chave explícita. Você pode substituir qualquer chave implícita especificando uma chave explícita.
Um cenário importante para recursos é quando você define um Style. Na verdade, um Style é quase sempre definido como uma entrada em um dicionário de recursos, porque os estilos são inerentemente destinados à reutilização. Para obter mais informações sobre estilos, consulte Estilos e modelos (WPF .NET).
Estilos para controles podem ser criados e referenciados com uma chave implícita. Os estilos de tema que definem a aparência padrão de um controle dependem dessa chave implícita. Do ponto de vista da solicitação, a chave implícita é a Type do próprio controle. Do ponto de vista da definição dos recursos, a chave implícita do estilo é o TargetType. Dessa forma, se você estiver criando temas para controles personalizados ou criando estilos que interagem com estilos de tema existentes, não será necessário especificar uma diretiva x:Key para isso Style. E se você quiser usar os estilos temáticos, não precisará especificar nenhum estilo. Por exemplo, a definição de estilo a seguir funciona, mesmo que o Style recurso não pareça ter uma chave:
<Style TargetType="Button">
<Setter Property="Background" Value="#4E1A3D" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="#4E1A3D"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Esse estilo realmente tem uma chave: a chave implícita: o System.Windows.Controls.Button
tipo. Na marcação, você pode especificar diretamente TargetType como o nome do tipo (ou, opcionalmente, pode usar {x:Type...} para retornar um Type.
Por meio dos mecanismos de estilo de tema padrão usados pelo WPF, esse estilo é aplicado como o estilo de tempo de execução de um Button na página, mesmo que o próprio Button não tente especificar sua propriedade Style ou uma referência de recurso específica para o estilo. O estilo que você definiu na página é encontrado mais cedo na sequência de pesquisa do que o estilo do dicionário de temas, utilizando a mesma chave deste. Você pode especificar <Button>Hello</Button>
em qualquer lugar da página, e o estilo que você definiu com TargetType de Button
seria aplicado a esse botão. Se desejar, você ainda pode especificar o estilo usando o mesmo valor de tipo igual a TargetType para dar clareza no seu código, embora isso seja opcional.
As chaves implícitas para estilos não são aplicáveis em um controle se OverridesDefaultStyle for true
. (Observe também que OverridesDefaultStyle pode ser definido como parte do comportamento nativo para a classe de controle, em vez de explicitamente em uma instância do controle.) Além disso, para dar suporte a chaves implícitas para cenários de classe derivadas, o controle deve substituir DefaultStyleKey (todos os controles existentes fornecidos como parte do WPF incluem essa substituição). Para obter mais informações sobre estilos, temas e design de controle, consulte Diretrizes para criar controles estilizáveis.
DataTemplate também tem uma chave implícita. A chave implícita para um DataTemplate é o valor da DataType propriedade. DataType também pode ser especificado como o nome do tipo em vez de usar explicitamente {x:Type...}. Para obter detalhes, consulte Visão geral da Modelagem de Dados.
Consulte também
- Recursos em código
- Dicionários de recursos mesclados
- Como definir e referenciar um recurso do WPF
- Como usar recursos do sistema
- Como usar recursos de aplicativo
- Extensão de marcação x:Type
- ResourceDictionary
- recursos do aplicativo
- Definir e referenciar um recurso
- Visão geral do gerenciamento de aplicativos
- Extensão de marcação StaticResource
- Extensão de marcação DynamicResource
.NET Desktop feedback