Sistema de estilos en Avalonia: Personalización avanzada de controles

Al desarrollar interfaces con Avalonia, la gestión de la apariencia mediante el sistema de estilos ofrece ventajas significativas sobre la asignación directa de propiedades en cada control. Este artículo explora en profundidad los mecanismos para definir y aplicar estilos, facilitando la creación de interfaces coherentes y adaptables a diferentes estados de interacción.

Organización de estilos en la estructura del proyecto

Los estilos pueden definirse en diferentes niveles para controlar su ámbito de aplicación. Para una reutilización óptima, se recomienda centralizarlos en archivos dedicados.

Archivo de estilos global (Styles.axaml):

<Styles xmlns="https://github.com/avaloniaui">
    <Style Selector="Button">
        <Setter Property="Background" Value="#4A90E2"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Padding" Value="12,8"/>
        <Setter Property="CornerRadius" Value="4"/>
    </Style>
</Styles>

Integración en App.axaml:

<Application.Styles>
    <StyleInclude Source="/Styles.axaml"/>
</Application.Styles>

Selector de estilos: Mecanismos de selección

Los selectores permiten especificar con precisión qué controles se verán afectados por una regla de estilo.

Selección por nombre de control:

<Style Selector="TextBlock#tituloPrincipal">
    <Setter Property="FontSize" Value="24"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Margin" Value="0,0,0,16"/>
</Style>

Clases personalizadas para agrupación:

<Style Selector="Button.icono">
    <Setter Property="Width" Value="48"/>
    <Setter Property="Height" Value="48"/>
    <Setter Property="Padding" Value="8"/>
</Style>

<Style Selector="Button.peligro">
    <Setter Property="Background" Value="#E74C3C"/>
    <Setter Property="BorderBrush" Value="#C0392B"/>
</Style>

En el XAML del control:

<Button Classes="icono peligro" Content="×"/>

Combinación de selectores:

<!-- Botón con clase 'activo' en estado de puntero -->
<Style Selector="Button.activo:pointerover">
    <Setter Property="Background" Value="#2ECC71"/>
</Style>

<!-- TextBox dentro de un Grid específico -->
<Style Selector="Grid#formulario TextBox">
    <Setter Property="Margin" Value="0,8"/>
</Style>

Propiedades dinámicas mediante disparadores

Los disparadores permiten modificar propiedades basadas en el estado actual del control o el valor de otras propiedades.

Disparador basado en propiedad:

<Style Selector="CheckBox">
    <Setter Property="Foreground" Value="#2C3E50"/>
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Foreground" Value="#27AE60"/>
        </Trigger>
    </Style.Triggers>
</Style>

Ejemplo completo con múltiples estados:

<Style Selector="Button.accion">
    <Setter Property="Background" Value="#3498DB"/>
    <Setter Property="Transitions">
        <Transitions>
            <BrushTransition Property="Background" Duration="0:0:0.2"/>
        </Transitions>
    </Setter>
</Style>

<Style Selector="Button.accion:pointerover">
    <Setter Property="Background" Value="#2980B9"/>
</Style>

<Style Selector="Button.accion:pressed">
    <Setter Property="Background" Value="#1F618D"/>
</Style>

Sistema de recursos para valores compartidos

Los recursos permiten centralizar valores como colores, pinceles y dimensiones para mantener consistencia.

Definición de recursos:

<Window.Resources>
    <Color x:Key="ColorPrimario">#3498DB</Color>
    <Color x:Key="ColorSecundario">#2ECC71</Color>
    
    <SolidColorBrush x:Key="PincelPrimario" Color="{StaticResource ColorPrimario}"/>
    <SolidColorBrush x:Key="PincelSecundario" Color="{StaticResource ColorSecundario}"/>
    
    <CornerRadius x:Key="RadioBorde">6</CornerRadius>
    <Thickness x:Key="EspaciadoEstandar">16</Thickness>
</Window.Resources>

Uso en estilos:

<Style Selector="Panel.principal">
    <Setter Property="Background" Value="{DynamicResource PincelPrimario}"/>
    <Setter Property="Padding" Value="{StaticResource EspaciadoEstandar}"/>
</Style>

Plantillas de control para personalización profunda

Cuando se necesita alterar radicalmente la estructura visual de un control, se utiliza una plantilla de control.

Ejemplo de botón con plantilla personalizada:

<Style Selector="Button.botonPersonalizado">
    <Setter Property="Template">
        <ControlTemplate>
            <Border Name="contenedorPrincipal"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    CornerRadius="8"
                    Margin="2">
                <StackPanel Orientation="Horizontal" 
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Spacing="8">
                    <Path Name="icono" 
                          Data="{TemplateBinding Tag}"
                          Width="16" Height="16"
                          Fill="{TemplateBinding Foreground}"/>
                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </StackPanel>
            </Border>
            
            <ControlTemplate.Styles>
                <Style Selector="Border:pointerover">
                    <Setter Property="Opacity" Value="0.9"/>
                </Style>
            </ControlTemplate.Styles>
        </ControlTemplate>
    </Setter>
</Style>

Especificidad y resolución de conflictos

Cuando múltiples estilos aplican al mismo control, se resuelve mediante reglas de especificidad:

  1. Propiedades establecidas directamente en el control (mayor prioridad)
  2. Selectores con identificador (#id)
  3. Selectores con clase (.clase)
  4. Selectores por tipo de control
  5. Estilos heredados de temas base

Para forzar un estilo específico, se puede utilizar la sintaxis de adjuntos o establecer propiedades directamente en el XAML del control.

Herramientas de depuración

Avalonia DevTools (accesible con F12) permite inspeccionar los estilos aplicados a cada control, ver propiedades heredadas y diagnosticar conflictos. Esta herramienta es esencial para resolver problemas cuando los estilos no se aplican como se espera.

El sistema de estilos de Avalonia proporciona un mecanismo potente para crear interfaces modernas y mantenibles, con soporte completo para estados de interacción, temas personalizados y reutilización de componentes visuales.

Etiquetas: Avalonia XAML estilos selectores plantillas-de-control

Publicado el 6-18 21:28