Compartir a través de


Cómo crear un estilo para un control

Con Windows Presentation Foundation (WPF), puedes personalizar la apariencia de un control existente con tu propio estilo reutilizable. Los estilos se pueden aplicar globalmente a la aplicación, las ventanas y las páginas, o directamente a los controles.

Crear un estilo

Puede considerar un Style como una manera cómoda de aplicar un conjunto de valores de propiedad a uno o varios elementos. Puede usar un estilo en cualquier elemento que derive de FrameworkElement o FrameworkContentElement, como un Window o un Button.

La forma más común de declarar un estilo es como un recurso en la Resources sección de un archivo XAML. Dado que los estilos son recursos, cumplen las mismas reglas de ámbito que se aplican a todos los recursos. En pocas palabras, donde declaras un estilo afecta dónde se puede aplicar el estilo. Por ejemplo, si declaras el estilo en el elemento raíz del archivo XAML de definición de aplicación, el estilo se puede usar en cualquier parte de la aplicación.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Si declaras el estilo en uno de los archivos XAML de la aplicación, el estilo solo se puede usar en ese archivo XAML. Para obtener más información sobre las reglas de ámbito de los recursos, consulta Introducción a los recursos XAML.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        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"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Un estilo se compone de <Setter> elementos secundarios a los que se establecen propiedades en los elementos a los que se aplica el estilo. En el ejemplo anterior, observe que el estilo se establece para aplicar a los tipos TextBlock a través del atributo TargetType. El estilo establecerá el FontSize en 15 y el FontWeight en ExtraBold. Agregue un <Setter> para cada propiedad cuyo estilo sea cambiado.

Aplicar un estilo implícitamente

Una Style es una manera cómoda de aplicar un conjunto de valores de propiedad a más de un elemento. Por ejemplo, considere los siguientes TextBlock elementos y su apariencia predeterminada en una ventana.

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Captura de pantalla de ejemplo de estilo anterior

Puede cambiar la apariencia predeterminada estableciendo propiedades, como FontSize y FontFamily, en cada TextBlock elemento directamente. Sin embargo, si quieres que los TextBlock elementos compartan algunas propiedades, puedes crear un Style elemento en la Resources sección del archivo XAML, como se muestra aquí.

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Cuando estableces el TargetType de tu estilo en el TextBlock tipo y omites el x:Key atributo, el estilo se aplica a todos los TextBlock elementos con ámbito al estilo, que suele ser el propio archivo XAML.

Ahora los TextBlock elementos aparecen como se indica a continuación.

Captura de pantalla de estilo base de muestra

Aplicar un estilo explícitamente

Si agrega un x:Key atributo con valor al estilo, el estilo ya no se aplica implícitamente a todos los elementos de TargetType. Solo los elementos que hacen referencia explícitamente al estilo tendrán aplicado el estilo.

Este es el estilo de la sección anterior, pero declarado con el x:Key atributo .

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Para aplicar el estilo, establezca la propiedad Style del elemento al valor x:Key mediante una extensión de marcado StaticResource, como se muestra aquí.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Observe que el primer TextBlock elemento tiene el estilo aplicado mientras que el segundo elemento TextBlock permanece sin cambios. El estilo implícito de la sección anterior se cambió a un estilo que declaró el x:Key atributo, lo que significa que el único elemento afectado por el estilo es el que hizo referencia al estilo directamente.

Ejemplo de estilo de bloque de texto en captura de pantalla

Una vez que se aplica un estilo, explícita o implícitamente, se sella y no se puede cambiar. Si desea cambiar un estilo que se ha aplicado, cree un nuevo estilo para reemplazar el existente. Para obtener más información, consulte la propiedad IsSealed.

Puede crear un objeto que elija un estilo que se aplique en función de la lógica personalizada. Para obtener un ejemplo, vea el ejemplo proporcionado para la StyleSelector clase .

Aplicar un estilo mediante programación

Para asignar un estilo con nombre a un elemento mediante programación, obtenga el estilo de la colección resources y asígnelo a la propiedad del Style elemento. Los elementos de una colección de recursos son de tipo Object. Por lo tanto, debe convertir el estilo recuperado a un System.Windows.Style antes de asignarlo a la propiedad Style. Por ejemplo, el código siguiente establece el estilo de un TextBlock denominado textblock1 en el estilo TitleTextdefinido.

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

Extender un estilo

Quizás desee que los dos TextBlock elementos compartan algunos valores de propiedad, como el FontFamily y el centrado de HorizontalAlignment. Pero también quiere que el texto Mis imágenes tenga algunas propiedades adicionales. Puede hacerlo creando un nuevo estilo basado en el primer estilo, como se muestra aquí.

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

A continuación, aplique el estilo a un TextBlock.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Este TextBlock estilo ahora está centrado, utiliza una Comic Sans MS fuente con un tamaño de 26 y el color de primer plano está establecido en el LinearGradientBrush que se muestra en el ejemplo. Observe que invalida el FontSize valor del estilo base. Si hay más de una Setter que apunta a la misma propiedad en una Style, la Setter que se declara por última vez tiene prioridad.

A continuación se muestra el aspecto de los TextBlock elementos:

Bloques de texto estilizados

Este TitleText estilo amplía el estilo que se ha creado para el TextBlock tipo, al que se hace referencia con BasedOn="{StaticResource {x:Type TextBlock}}". También puede extender un estilo que tenga un x:Key mediante el x:Key del estilo . Por ejemplo, si hubiera un estilo denominado Header1 y quisiera ampliar ese estilo, usaría BasedOn="{StaticResource Header1}".

Relación de la propiedad TargetType y el atributo x:Key

Como se ha mostrado anteriormente, establecer la TargetType propiedad en TextBlock sin asignar un x:Key causa que el estilo se aplique a todos los TextBlock elementos. En este caso, el x:Key se establece implícitamente en {x:Type TextBlock}. Esto significa que si establece explícitamente el valor x:Key en algo distinto de {x:Type TextBlock}, Style no se aplica automáticamente a todos los elementos TextBlock. En su lugar, debe aplicar el estilo (mediante el valor x:Key) a los elementos TextBlock explícitamente. Si su estilo está en la sección de "resources" y no establece la propiedad en su estilo, entonces debe establecer el atributo TargetType.

Además de proporcionar un valor predeterminado para x:Key, la TargetType propiedad especifica el tipo al que se aplican las propiedades de establecedor. Si no especifica un TargetType, debe calificar las propiedades de los objetos Setter con un nombre de clase mediante la sintaxis Property="ClassName.Property". Por ejemplo, en lugar de establecer Property="FontSize", debe establecer Property en "TextBlock.FontSize" o "Control.FontSize".

Tenga en cuenta también que muchos controles WPF constan de una combinación de otros controles WPF. Si crea un estilo que se aplica a todos los controles de un tipo, puede obtener resultados inesperados. Por ejemplo, si crea un estilo destinado al tipo TextBlock en un Window, el estilo se aplica a todos los controles TextBlock de la ventana, incluso si el TextBlock es parte de otro control, como un ListBox.

Consulte también