Recursos y estilos

Recursos

Son elementos que tienen un identificador único y pueden ser referenciados por algún otro elemento para su reutilización.

La clase “FrameworkElement” expone una propiedad llamada Resources, la cual representa el diccionario de recursos del elemento en cuestión. Asimismo, la clase Application incluye la propiedad Resources para poder dar de alta recursos globales a toda la aplicación.

<UserControl.Resources>
  <SolidColorBrush x:Key="BrochaAzul" Color="Blue" />
</UserControl.Resources>

O bien podemos agregarlo al diccionario de recursos de la aplicación.

<Application.Resources>
  <SolidColorBrush x:Key="BrochaAzul" Color="Blue" />
</Application.Resources>

En Resources podemos declarar cualquier objeto .NET siempre y cuando su espacio de nombres XML esté al alcance.

<UserControl xmlns:core="clr-namespace:System;assembly=mscorlib">
<!--El resto de atributos de UserControl ha sido omitido por brevedad -->
<UserControl.Resources>
  <core:Double x:Key="numero">300</core:Double>
  <core:String x:Key="cadena">Esto es una cadena hecha recurso</core:String>
</UserControl.Resources>

 Referenciando recursos

Utilizaremos la extensión del lenguaje de marcado {StaticResource}.

<Ellipse Width="100" Height="100" Fill="{StaticResource BrochaAzul}" />

Ámbito de los diccionarios

Podemos tener un objeto en el diccionario de recursos de un Grid, también con el identificador “BrochaAzul” en cuyo caso se utilizará el diccionario más inmediato (el del Grid y no el del UserControl).

<UserControl.Resources>
  <SolidColorBrush x:Key="BrochaAzul" Color="Blue" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
  <Grid.Resources>
    <SolidColorBrush x:Key="BrochaAzul" Color="DarkBlue" />
  </Grid.Resuorces>
  <Ellipse Width="100" Height="100" Fill"{StaticResource BrochaAzul}" />
</Grid>
</UserControl>

Creando recursos con Expression Blend

Vídeo creación de recursos con Expression.

Estilos

Muchas veces los elementos de diseño deben ser reutilizados. Por ejemplo piensa en que todos los bloques de texto tengan la misma apariencia. Se puede cambiar, cambiando las propiedades de cada uno de los bloques o bien hacerlo a través de Estilos, que resultará mucho más eficiente.

Son elementos del tipo <Style /> y generalemente declarados dentro de algún diccionario de recursos y por tanto con un identificador único. Son similares a los CSS.

<Style TargetType="TextBlock" x:Key="EstiloTextBlock"> 
  <Setter Property="FontFamily" Value="Arial Black" />
  <Setter Property="FontSize" Value="18" />
</Style>

Este estilo se aplicará a los TextBlock y clases derivadas. Las propiedades que deseamos cambiar están expresadas a través de los elementos Setter (Property y Value), el valor puede ser fijo o bien enlazado al valor de otra propiedad en otro objeto. Veamos un ejemplo:

<Style TargetType="TextBlock" x:Key="EstiloTextBlock"> 
  <Setter Property="FontFamily" Value="Arial Black" />
  <Setter Property="FontSize" Value="18" />
  <Setter Property="Foreground" Value={Binding Foreground, ElementName=LayoutRoot}" />
</Style>

Aplicando estilos

Para utilizar un estilo si está dentro de algún diccionario de recursos, lo referenciamos como cualquier otro recurso a través de la extesión {StaticResource}. La propiedad Style está implementada en la clase base FrameworkElement, por lo que todo elemento que herede de forma directa o indirecta de esta clase base puede ser estilizado.

<TextBlock Style="{StaticResource EstiloTextBlock}" Text="Prueba de texto" />

También podemos realizarlo mediante código C#:

TextBlock textBlock = new TextBlock() {Text="Nuevo texto"};
var style =LayoutRoot.Resources["EstiloTextBlock"] as Style;
textBlock.Style = style;

Propiedad TargetType

Como hemos visto antes TargetType de la clase Style indica el tipo al que este estilo puede ser aplicado. Esta clase puede ser una clase abstracta base para poder crear estilos polimórficos.

<Style TargetType="Shape" x:Key="EstiloBase">
  <Setter Property="Fill" Value="Red" />
  <Setter Property="Stroke" Value="Black" />
  <Setter Property="StrokeThickness" Value="5" />
  <Setter Property="Width" Value="100" />
  <Setter Property="Height" Value="100" />
</Style>

Luego podremos utilizar:

<Rectangle Style="{StaticResource EstiloBase}" />
<Ellipse Style="{StaticResource EstiloBase}" />

Propiedad BasedOn

Esta propiedad nos permite establecer cuál es el estilo del que se basa el estilo en cuestión. Esto hace posible que podamos crear estilos en cascada de igual manera que lo hace CSS.

<Style TargetType=Rectangle" x:Key="EstiloRectangulo" BasedOn="{StaticResource EstiloBase}">
  <Setter Property="RadiusX" Value="20" />
  <Setter Property="RadiusY" Value="20" />
</Style>

Estilos implícitos

Silverlight cuenta con una serie de estilos que son aplicables a todos los elementos de un mismo tipo.

Se declaran de la misma manera pero sin utilizar el atributo x:key, de esta forma se aplicaría a todos los elementos del tipo indicado.

<Style TargetType="Button">
  <Setter Property="Width" Value="100" />
  <Setter Property="Height" Value="40" />
  <Setter Property="Margin" Value="2" />
  <Setter Property="Content" Value="Botón" />
</Style>

Temas

Podemos crear temas para las aplicaciones Silverlight ya que contamos con estilos implícitos y combinándolo con diccionarios de recursos mezclados, podríamos aplicar uno u otro diccionario de manera dinámica.

<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Green"/>
  </Style>
  <Style TargetType="Button">
    <Setter Property="Foreground" Value="Green" />
  </Style>
  <Style TargetType="ListBox">
    <Setter Property="Foreground" Value="Green"></Setter>
  </Style>
  <Style TargetType="RadioButton">
    <Setter Property="Foreground" Value="Green"></Setter>
  </Style>
  <Style TargetType="CheckBox">
    <Setter Property="Foreground" Value="Green"></Setter>
  </Style>
</ResourceDictionary>

Diseñamos una interface:

El código fuente de los botones sería:

        
        private void BtnRojo_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Resources.MergedDictionaries.Clear();
            Application.Current.Resources.MergedDictionaries.Add(
                new ResourceDictionary() { Source = new Uri("Rojo.xaml", UriKind.RelativeOrAbsolute) });

        }

        private void BtnVerde_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Resources.MergedDictionaries.Clear();
            Application.Current.Resources.MergedDictionaries.Add(
                new ResourceDictionary() { Source = new Uri("Verde.xaml", UriKind.RelativeOrAbsolute) });

        }

Los diccionarios Verde.xaml y Rojo.xaml tienen que estar marcados como “Contenido” a la hora de Construir la aplicación.

Diccionario de recursos mezclados

Si quisieramos desde el UserControl o Page utilizar los diccionarios  se haría de la siguiente manera:

<Page.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="Dic1.xaml"/>
      <ResourceDictionary Source="Dic2.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Page.Resources>

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.