TOC

This article is currently in the process of being translated into Spanish (~33% done).

Estilos:

Using WPF styles

En el capítulo anterior, donde introdujimos el concepto de estilos, usamos un ejemplo muy sencillo de estilos definidos localmente, orientados a un tipo específico de control - El TextBlock. Sin embargo, los estilos pueden ser definidos para diferentes ámbitos, dependiendo de dónde y cómo quieras usarlos, incluso puedes limitar estilos para que sólo se usen en controles cuando se quiera explícitamente. En este capítulo, te mostraré las diferentes maneras en las que los etilos pueden definirse.

Local control specific style

Puedes definir estilos directamente en un control, de esta manera:

<Window x:Class="WpfTutorialSamples.Styles.ControlSpecificStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ControlSpecificStyleSample" Height="100" Width="300">
    <Grid Margin="10">
        <TextBlock Text="Style test">
            <TextBlock.Style>
                <Style>
                    <Setter Property="TextBlock.FontSize" Value="36" />
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </Grid>
</Window>

En este ejemplo, el estilo sólo afecta a este control TextBlock específico, entonces, ¿para qué molestarse? Bueno, en este caso, no tiene ningún sentido. Podría haber reemplazado todo ese código extra con una sola propiedad FontSize en el control TextBlock, pero como veremos más adelante, los estilos pueden hacer un poco más que simplemente establecer propiedades, por ejemplo, los disparadores de estilo podrían hacer que el ejemplo anterior fuera útil en un aplicación de la vida real. Sin embargo, la mayoría de los estilos que definirá probablemente abarcarán un ámbito superior.

Local child control style

Utilizando la sección Resources de un control, puedes abarcar controles hijos de este control (y controles hijos de esos controles hijos, etc.). Esto es básicamente lo que hicimos en el ejemplo de introducción en el último capítulo, que se veía así:

<Window x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SimpleStyleSample" Height="200" Width="250">
    <StackPanel Margin="10">
        <StackPanel.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="Foreground" Value="Gray" />
                <Setter Property="FontSize" Value="24" />
            </Style>
        </StackPanel.Resources>
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

This is great for the more local styling needs. For instance, it would make perfect sense to do this in a dialog where you simply needed a set of controls to look the same, instead of setting the individual properties on each of them.

Window-wide styles

The next step up in the scope hierarchy is to define the style(s) within the Window resources. This is done in exactly the same way as above for the StackPanel, but it's useful in those situations where you want a specific style to apply to all controls within a window (or a UserControl for that matter) and not just locally within a specific control. Here's a modified example:

<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WindowWideStyleSample" Height="200" Width="300">
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

As you can see, the result is exactly the same, but it does mean that you could have controls placed everywhere within the window and the style would still apply.

Application-wide styles

If you want your styles to be used all over the application, across different windows, you can define it for the entire application. This is done in the App.xaml file that Visual Studio has likely created for you, and it's done just like in the window-wide example:

App.xaml

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	 StartupUri="Styles/WindowWideStyleSample.xaml">
    <Application.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Application.Resources>
</Application>

Window

<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ApplicationWideStyleSample" Height="200" Width="300">
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

Explicitly using styles

You have a lot of control over how and where to apply styling to your controls, from local styles and right up to the application-wide styles, that can help you get a consistent look all over your application, but so far, all of our styles have targeted a specific control type, and then ALL of these controls have used it. This doesn't have to be the case though.

By setting the x:Key property on a style, you are telling WPF that you only want to use this style when you explicitly reference it on a specific control. Let's try an example where this is the case:

<Window x:Class="WpfTutorialSamples.Styles.ExplicitStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExplicitStyleSample" Height="150" Width="300">
    <Window.Resources>
        <Style x:Key="HeaderStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock Style="{StaticResource HeaderStyle}">Header 2</TextBlock>
        <TextBlock>Header 3</TextBlock>
    </StackPanel>
</Window>

Notice how even though the TargetType is set to TextBlock, and the style is defined for the entire window, only the TextBlock in the middle, where I explicitly reference the HeaderStyle style, uses the style. This allows you to define styles that target a specific control type, but only use it in the places where you need it.

Summary

WPF styling allows you to easily re-use a certain look for your controls all over the application. Using the x:Key property, you can decide whether a style should be explicitly referenced to take effect, or if it should target all controls no matter what.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!