Creación de estilos para los controles de WPF

Author Top
Pablo

A las personas que están empezando en WPF les puede interesar mucho personalizar sus controles para que se vean de la forma que desean, para esto existen los estilos, sin embargo este tema suele ser algo complejo al principio ya que no se parece en nada a los estilos de CSS para las páginas web, es por esto que en el presente blog se explicará un pequeño ejemplo que puede ser muy beneficioso.

Para explicar este tema se modificara un botón, primero una modificación básica y después una más compleja.

 

1. Crear la página con el control

Se crea una página principal en WPF que solo contendrá el botón

 

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        
    </Window.Resources>
    <Grid>
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Ejemplo"></Button>
    </Grid>
</Window>

Resultado:

Botón sin estilo

2. Se crea un estilo muy básico

En la sección de recursos de nuestra página agregamos un color gradiente entre blanco y morado para utilizar en el botón, este es un tema aparte si desea para más información visite gradientes, además creamos el  estilo BotonMorado este solamente pondrá algunos valores básicos a las propiedades del botón como lo son el color de fondo, color de borde, y estilo de fuente, es importante explicar que el x:Key="BotonMorado" es el identificador del estilo y el  TargetType="Button" indica para que control fue creado el estilo, entonces que deseemos aplicarle el estilo se le especificará Style="{StaticResource BotonMorado}", sin embargo habrá momentos en que deseemos que el estilo se aplique a todos los controles para el cual fue creado para esto en su identificador pondríamos x:Name="Button" en lugar de x:Key="BotonMorado".

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Background="Gray" >
    <Window.Resources>
        <LinearGradientBrush x:Key="ColorBoton" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="BlueViolet"  Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>
        
        <Style x:Name="Button" TargetType="Button" >
            <Setter Property="Background"  Value="{StaticResource ColorBoton}" />
            <Setter Property="BorderBrush" Value="White"/>
            <Setter Property="Foreground"  Value="White"/>
            <Setter Property="FontFamily"  Value="Arial"/>
            <Setter Property="FontWeight"  Value="Bold"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Ejemplo"></Button>
    </Grid>
</Window>

El resultado sería el siguiente:

Botón Morado

3. Creación de un estilo que modifique la estructura del control

En el ejemplo anterior el estilo consistió en solamente indicar algunas propiedades del control, esto es muy simple aunque útil, a pesar de esto nuestro control no tuvo un cambio relevante, para hacer cambios un poco más “creativos” se necesita modificar su ControlTemplate, en el siguiente ejemplo hacemos esto para obtener un botón redondo, al indicar el CornerRadius en el Border del ControlTemplate en el cual se le agrega un efecto de sombra DropShadowEffect, también se agrega una sección de triggers(ControlTemplate.Triggers) que como su nombre indica son disparadores que ocurren en un evento determinado en este caso cuando se enfoca el control con el mouse IsMouseOver,  y cuando se presiona IsPressed haciendo que cambie su color de fondo y de borde.

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <LinearGradientBrush x:Key="ColorNormal" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#CCC" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="ColorDeBordeNormal" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#CCC" Offset="0.0"/>
                    <GradientStop Color="#444" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <Style x:Key="EstiloEjemplo" TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border x:Name="Border"  
                                CornerRadius="30" 
                                BorderThickness="1"
                                Width="60"
                                Height="60"
                                Background="{StaticResource ColorNormal}"
                                BorderBrush="Black" >
                            <ContentPresenter 
                                Margin="2"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                RecognizesAccessKey="True"/>

                            <Border.Effect>
                                <DropShadowEffect/>
                            </Border.Effect>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter TargetName="Border" Property="Background" >
                                    <Setter.Value>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientBrush.GradientStops>
                                                <GradientStopCollection>
                                                    <GradientStop Color="#FFF" Offset="0.0"/>
                                                    <GradientStop Color="#AAA" Offset="1.0"/>
                                                </GradientStopCollection>
                                            </GradientBrush.GradientStops>
                                        </LinearGradientBrush>
                                    </Setter.Value>
                                </Setter> 
                            </Trigger>

                            <Trigger Property="IsPressed" Value="true">
                                <Setter TargetName="Border" Property="Background">
                                    <Setter.Value>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientBrush.GradientStops>
                                                <GradientStopCollection>
                                                    <GradientStop Color="#BBB" Offset="0.0"/>
                                                    <GradientStop Color="#EEE" Offset="0.1"/>
                                                    <GradientStop Color="#EEE" Offset="0.9"/>
                                                    <GradientStop Color="#FFF" Offset="1.0"/>
                                                </GradientStopCollection>
                                            </GradientBrush.GradientStops>
                                        </LinearGradientBrush>
                                    </Setter.Value>
                                </Setter>

                                <Setter TargetName="Border" Property="BorderBrush">
                                    <Setter.Value>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientBrush.GradientStops>
                                                <GradientStopCollection>
                                                    <GradientStop Color="#CCC" Offset="0.0"/>
                                                    <GradientStop Color="#444" Offset="1.0"/>
                                                </GradientStopCollection>
                                            </GradientBrush.GradientStops>
                                        </LinearGradientBrush>
                                    </Setter.Value> 
                                </Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <Button Style="{StaticResource EstiloEjemplo}" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Ejemplo"></Button>
    </Grid>
</Window>

Resultado:

Botón Redondo

Con el Mouse sobre:

Botón Redondo MouseOver

Presionado:

Botón Redondo IsPressed

Es evidente que es más difícil cambiar el ControlTemplate, más aun cuando varían de control a control por ejemplo el del ComboBox es más complejo para ver ejemplos muy buenos de los controles los invito a visitar la página de Microsoft, lógicamente es muy difícil que en estos venga un control igual al que deseamos pero nos facilita su construcción al conocer la estructura del ControlTemplate.

Como pudimos observar los estilos de WPF son muy diferentes a los de CSS, sin embargo se puede hacer muchas cosas como si fuera CSS( muchas cosas pero NO todas ), los estilos le pueden dar mucha personalidad a la aplicación a pesar de la dificultad de su creación un ejemplo muy claro es un DataGrid, un control muy complejo en estructura, y muy simple en visualización, pero que con estilos se puede llegar a ver mucho mejor.

Ejemplo:

Ejemplo DataGrid

 

Muchas gracias por leer el post espero que les sea de ayuda!! Smile