[email protected]

Asunción, PARAGUAY

Ingeniería y desarrollo de software, emprendimiento, cursos

20 de marzo de 2014

Silverlight: Cambiar estilos en tiempo de ejecución

Silverlight

Introducción

En el mundo web, sobre todo, es muy importante el cambio continuo porque siempre se presentan nuevos desafíos. Pero, la realidad es que el mantenimiento de un sistema y/o aplicación tiene su costo (en tiempo y dinero). Es por esa situación que resulta importante el cambio de imagen sin afectar funcionalidad y practicidad. Esto lo podemos lograr con el lenguaje XAML, específicamente en Silverlight.

Contexto

En esta oportunidad me parece importante demostrar una capacidad de XAML para la administración de temas dentro de una aplicación Silverlight (out-of-the-browser).

Para cumplir con el objetivo de esta entrada, utilizaremos dos estilos (Azul y Amarillo) para ver distintos estilos que se pueden aplicar dentro de una aplicación Silverlight, por medio de un botón, sin necesidad de reiniciar la aplicación.

Utilizando el código

Para este ejemplo utilizaremos un proyecto 'Aplicación Silverlight', sin página Web contenida (para ello, desmarcaremos la opción 'Hospedar la aplicación Silverlight en un sitio web.').

TIP: Es importante ejecutar la aplicación (F5) a modo de prueba para evitar problemas con librerías y/o excepciones relacionados al Visual Studio.

Una vez creado el proyecto, procedemos a crear los estilos. En este caso, creé una carpeta 'Themes' con dos subcarpetas: 'Amarillo' y 'Azul'. Dentro de cada subcarpeta está contenido su respectivo estilo (que los llamé 'Style.xaml') con las definiciones propias de cada uno. La estructura de los temas se vería de la siguiente manera:
Estructura Temas

Para poder crear estilos necesitamos un componente nuevo en nuestras subcarpetas que se denomina 'ResourceDictionary', que básicamente provee los recursos a la aplicación que estamos desarrollando. Mas información aquí (en inglés).

Es en este punto donde debemos definir los estilos en los archivos 'Style.xaml', primeramente veamos la estructura del estilo para 'Amarillo'.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
    <Style TargetType="Rectangle">
        <Setter Property="Fill" Value="Yellow" />
    </Style>
</ResourceDictionary>

En la defición de archivo de recurso (presentado arriba) vemos que creamos un estilo para el elemento 'Rectangle' que sea de color amarillo. Luego de definir el color amarillo, pasamos a definir el color Azul, siguiendo las mismas directrices:
<ResourceDictionary
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
     <Style TargetType="Rectangle">
         <Setter Property="Fill" Value="Blue" />
     </Style>
     <Style TargetType="sdk:Label">
         <Setter Property="Background" Value="BlueViolet"/>
         <Setter Property="BorderBrush" Value="DarkOrange"/>
         <Setter Property="BorderThickness" Value="2" />
         <Setter Property="Foreground" Value="Azure" />
     </Style>
 </ResourceDictionary>

Se debe tener en cuenta, que ambos archivos (Style.xaml) deben tener marcada la opción 'Acción de compilación' con 'Resource'. Para cumplir con dicho objetivo debemos hacer clic derecho sobre los archivos 'Style.xaml' --> Propiedades. ¡Y listo!

Muy importante es colocar las siguientes líneas en el archivo 'App.xaml', pues definen los colores a utilizar la primera vez que aplicamos el tema (por defecto):
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 x:Class="SilverlightApplication1.App"
 >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Themes/Amarillo/Style.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
     </Application.Resources>
</Application>

Para este ejemplo, utilizaremos el siguiente código XAML, para definir un rectágulo del color básico, una etiqueta y un botón, todo esto en el archivo 'MainPage.xaml':
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication1.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Rectangle Grid.Column="0" Width="200" Height="200" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <sdk:Label Content="Soy el texto" Width="100" Height="25" />

        <ToggleButton x:Name="btnBoton" Grid.Column="1" Width="150" Height="20" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Amarillo/Azul" Click="ToggleButton_Click_1" Style="{x:Null}" />
    </Grid>
</UserControl>
Por último, agregamos las acciones que realizará el botón. Básicamente el control cambiará los archivos de estilos según vaya necesitando. ¡No dudes en dejar las preguntas en los comentarios!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Resources;
using System.Windows.Shapes;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void ToggleButton_Click_1(object sender, RoutedEventArgs e)
        {
            string template = "Amarillo";
            if (this.btnBoton.IsChecked != null && this.btnBoton.IsChecked.Value)
            {
                template = "Azul";
            }

            App aplicacion = ((App)Application.Current);

            StreamResourceInfo resourceInfo = App.GetResourceStream(
                    new Uri("/SilverlightApplication1;component/Themes/"+template+"/Style.xaml", 
                    UriKind.Relative));

            StreamReader resourceReader = new StreamReader(resourceInfo.Stream);
            string xaml = resourceReader.ReadToEnd();
            ResourceDictionary diccionario = XamlReader.Load(xaml) as ResourceDictionary;

            //Eliminamos el estilo previamente cargado
            aplicacion.Resources.MergedDictionaries.Clear();

            //Agregamos el estilo que queremos cargar
            aplicacion.Resources.MergedDictionaries.Add(diccionario);
        }
    }
}

Puntos de interés

De manera sencilla se puede implementar el cambio de temas utilizando la técnica de Estilos implícitos, que no demanda mucho esfuerzo, pues únicamente cambiando los colores, tamaños y formas podremos tener a mano una infinidad de temas. La aplicación con el tema Amarillo se vería así:
Amarillo

Mientras que la aplicación con el tema Azul se vería así: Azul

Conclusión

Como hemos visto en este artículo la implementación de un sistema que cambie su interfaz gráfica no es una tarea muy complicada, pues solamente se necesita cambiar algunos archivos para presentar al usuario una gama de opciones para que su sistema siempre presente cambios visuales y/o estéticos.

Hey, we've just launched a new custom color Blogger template. You'll like it - https://t.co/quGl87I2PZ
Suscribíte al boletín