WPF - Usando Resources
A WPF utiliza o termo resource para se referir a dois tipos de coisas distintas:
1 - O primeiro tipo de resource refere-se a itens usados pelo programa que não são criados via código. Isto inclui imagens ou ícones que são fornecidos fora do código e são conhecidos como Assembly Resources.
2- A WPF também usa o termo para descrever código de objetos que são armazenados em um objeto dicionário e então usados em outras partes do código;
As Bibliotecas de classe de uso geral costumam oferecer classes chamadas de dicionários, que você pode usar para armazenar itens que você deseja salvar e recuperar depois. Um dicionário é um recipiente que armazena pares chave-valor, onde o valor é o objeto que você deseja armazenar, e a chave é o objeto que você usa para procurar, depois que ele é armazenado.
Dessa forma a WPF fornece um dicionário de classe chamado ResourceDictionary que é a base de recursos lógicos do WPF.
A classe ResourceDictionary implementa um dicionário para o qual você pode colocar referências a objetos de qualquer tipo, usando chaves de qualquer tipo.
Os objetos são sempre armazenadas como referências do tipo objeto, então depois de recuperá-los do dicionário, você deve lançá-los de volta para seu tipo original.
A classe FrameworkElement tem uma propriedade chamada de Resources do tipo ResourceDictionary e todos os elementos derivados de FrarmeworkElement contém este container pré-embutido. Na figura abaixo temos um esquema da hierarquia da herança onde podemos ver que todos os controles herdam a propriedade Resources .
As setas apontam da classe derivada para classe base. |
Neste artigo estamos enfocando o segundo significado e neste caso usar recursos permite que você reutilize código XAML através da definição de valores que você pode usar a partir de muitos lugares em um arquivo XAML.(Não vou entrar em detalhes sobre como usar o ResourceDictionary)
Como os arquivos XAML são gráficos , os resources tendem também a serem gráficos sendo que eles definem objetos e valores que representam propriedades de controles que você pode aplicar a muitos controles com o objetivo de dar uma aparência e comportamento similar.
A criação e utilização de um resource é muito simples e para definir um resource basta incluir a propriedade de um elemento Resources a um objeto como um Grid, Window ou outro container. Dentro deste elemento você inclui os recursos que você irá utilizar posteriormente. Cada recurso é um elemento tal qual um objeto ou um simples valor como um integer ou string.
Ao definir um recurso você deve dar ao mesmo um nome único através do atributo x:Key para identificá-lo.
Para entender melhor vamos a um exemplo prático:
Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo WPF Application com o nome wpf_Resources;
A seguir definia no código XAML do arquivo MainWindow.xaml o recurso conforme a seguir:
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Usando Resources" Height="350" Width="525"> <Window.Resources> <LinearGradientBrush x:Key="brButton" StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Yellow" Offset="0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Blue" Offset="1"/> </LinearGradientBrush> <BitmapEffectGroup x:Key="bmeButton"> <DropShadowBitmapEffect/> </BitmapEffectGroup> </Window.Resources> <Grid> </Grid> </Window> |
O código acima define um elemento Resources que contém um RadialGradientBrush chamado brButton e um BitmapEffectGroup chamado bmeButton.
Este elemento Resources esta contido no elemento Window do arquivo: <Window.Resources>
Qualquer objeto contido no objeto que trata o elemento Resources pode usar o recurso. No exemplo acima Window contém o elemento Resources de forma que qualquer objeto em Window pode usar o recurso.
Após definir uma simples propriedade de recurso tal como fizemos, podemos usá-lo. O valor que você dá ao atributo deverá ter o formato {StaticResource nome_recurso}, onde você coloca em nome_recurso o nome do recurso definido.
Para usar o recurso definido vamos definir no código XAML um Button e definir sua propriedade BackGround para o recurso brButton e a sua propriedade BitMapEffect para o recurso bmeButton conforme abaixo:
O resultado pode ser visto na janela do descritor WPF onde vemos o button usando o recurso definido.
StaticResource e DynamicResource
Quando você atribui uma referência de recurso a uma propriedade ele pode ser atribuído tanto como um StaticResource ou como um DynamicResource.
Apesar da nomenclatura, não são os próprios recursos que são estáticos ou dinâmicos, o mesmo recurso pode ser usado como um StaticResource quando atribuído a uma propriedade e como DynamicResource quando atribuído a outra. A diferença está em saber se a referência no ResourceDictionary é acompanhada por mudanças, que são então repassadas para a referenciação de propriedade do recurso.
Vejamos um exemplo prático para mostrar essa característica.
Inclua uma nova janela Window1.xaml no projeto wpf_Resources e a seguir defina o seguinte código XAML no arquivo Window1.xaml:
<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Window.Resources> <LinearGradientBrush x:Key="gradBrush" StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="BurlyWood" Offset="1"/> </LinearGradientBrush> </Window.Resources> <Grid> <StackPanel Background="{DynamicResource gradBrush}" Name="sp"> <TextBlock FontFamily="Arial Black" Margin="7" Background="{DynamicResource gradBrush}"> <- Buttons - DynamicResource </TextBlock> <Button Height="40" Name="btn1" FontWeight="Bold" Background="{StaticResource gradBrush}"> <- Button 1 - StaticResource </Button> <Button Height="40" Name="btn2" FontWeight="Bold" Background="{DynamicResource gradBrush}"> <- Button 2 - DynamicResource </Button> <Button HorizontalAlignment="Right" Click="Button_Click">Alterar</Button> </StackPanel> </Grid> </Window> |
No código acima temos um botão usando o recurso como StaticResource e outro como DynamicResource.
A seguir vamos inclui o code-behind no arquivo Window1.xaml.vb referente ao evento Click do botão - Alterar:
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Me.Resources("gradBrush") = Brushes.HotPink End Sub |
Este código esta alterando o recurso gradBrush.
Executando o projeto teremos o seguinte resultado:
===> | ||
Janela inicial | Depois de alterar a propriedade |
Observe que o botão referenciado como StaticResource :
<Button Height="40" Name="btn1" FontWeight="Bold" Background="{StaticResource gradBrush}">
Não sofreu alteração.
Para definir um DynamicResource no code-behind devemos usar o método SetResourceReference com a seguinte sintaxe:
btn2.SetResourceReference(BackgroundProperty, "gradBrush" );
Assim temos um visão geral sobre os conceitos e propriedades de Resources da WPF.
Pegue o projeto completo aqui: wpf_Resources.zip
"E a ninguém na terra chameis vosso pai,
porque um só é o vosso Pai, o qual esta nos céus."
"Nem vos chameis mestres, porque um só é o vosso Mestre, que é o Cristo." Mateus
23:9-10
Referências: