Los estilos, por defecto, en wpf, en Avalonia, son neutros y distan de ser siempre adecuados para las tareas que necesitamos. En este artículo, me gustaría hablar sobre los conceptos básicos del trabajo con estilos y mostrar algunos ejemplos interesantes.

¿Por qué necesitamos estilos en el marco de Avalonia?
- Los estilos dan más libertad al personalizar elementos;
- No duplicar descripciones de artículos;
- Separe el marcado en sí y su diseño.
Un par de ejemplos
Para una mejor comprensión de los estilos, primero mire un ejemplo:
Botón redondeado (algo similar a un gnomo de ubuntu)
Para hacer esto, cree en la plantilla estándar (
cómo crear una plantilla ) un diseño simple de la pila del panel y un par de botones.
<StackPanel> <Button Margin = "20" Content = "Btn" /> <Button Margin = "20" Content = "Style Btn" /> </StackPanel>
Ahora podemos configurar los botones de fondo principal y colores de fuente, pero luego tendremos que duplicar el código. El estilo ayudará a evitar esta repetición.
Agregue el estilo apropiado a la ventana:
<Window.Styles> <Style Selector = "Button"> <Setter Property = "Foreground" Value = "# FFFFFFFF" /> <Setter Property = "BorderThickness" Value = "2" /> <Setter Property = "Background" Value = "# FFDD4812" /> <Setter Property = "BorderBrush" Value = "# FFFFFFFF" /> </Style> </Window.Styles>

Obtenemos algo similar, pero sería bueno redondear los bordes. Desafortunadamente, no importa cómo lo intentemos, es imposible redondear los bordes del botón, pero puede redondear los bordes de la plantilla responsable de mostrar el botón. Para hacer esto, agregue otro estilo:
<Style Selector = "Button / template / ContentPresenter"> <Setter Property = "CornerRadius" Value = "10" /> </Style>

Resultó casi similar, pero hay un problema: cuando pasas el cursor sobre el botón, aparece un marco gris (hola desde el estilo estándar).

Para hacer esto, vaya a la pseudo-clase
css : pointerover y agregue otro estilo:
<Style Selector = "Button: pointerover / template / ContentPresenter"> <Setter Property = "BorderBrush" Value = "# FFDD4812" /> </Style>

Mucho mejor
Pero, ¿qué sucede si quiero aplicar estilos solo a botones específicos?
Agregue un botón más a la plantilla y establezca el atributo
Clases en los botones que queremos "decorar".
<StackPanel> <Button Margin = "20" Content = "Btn" /> <Button Margin = "20" Classes = "btn" Content = "Style Btn" /> <Button Margin = "20" Classes = "btn" Content = "Style Btn" /> </StackPanel>
Y le indicaremos a los estilos que necesitamos influir solo en ciertas clases:
<Style Selector = "Button.btn / template / ContentPresenter"> <Setter Property = "CornerRadius" Value = "10" /> </Style> <Style Selector = "Button.btn"> <Setter Property = "Foreground" Value = "# FFFFFFFF" /> <Setter Property = "BorderThickness" Value = "2" /> <Setter Property = "Background" Value = "# FFDD4812" /> <Setter Property = "BorderBrush" Value = "# FFFFFFFF" /> </Style> <Style Selector = "Button: pointerover.btn / template / ContentPresenter"> <Setter Property = "BorderBrush" Value = "# FFDD4812" /> </Style>

Todo el código de la ventana <Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:Wind1.ViewModels;assembly=Wind1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Wind1.Views.MainWindow" Icon="/Assets/avalonia-logo.ico" Title="Wind1"> <Window.Styles> <Style Selector="Button.btn /template/ ContentPresenter"> <Setter Property="CornerRadius" Value="10" /> </Style> <Style Selector="Button.btn"> <Setter Property="Foreground" Value="#FFFFFFFF" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="Background" Value="#FFDD4812" /> <Setter Property="BorderBrush" Value="#FFFFFFFF" /> </Style> <Style Selector="Button:pointerover.btn /template/ ContentPresenter"> <Setter Property="BorderBrush" Value="#FFDD4812" /> </Style> </Window.Styles> <StackPanel> <Button Margin="20" Content="Btn" /> <Button Margin="20" Classes="btn" Content="Style Btn" /> <Button Margin="20" Classes="btn" Content="Style Btn" /> </StackPanel> </Window>
Otro ejemplo de estilo interesante.La casilla de verificación estándar tiene este aspecto:

La casilla de verificación mejorada es similar a Android (un poco)

Un poco de magia <Window.Styles> <Style Selector = "CheckBox.uberbox"> <Setter Property = "Template"> <Setter.Value> <ControlTemplate> <Grid> <Border Background = "# b0b0b0" Padding = "5" BorderBrush = "# 303030" CornerRadius = "5"> <Grid> <Grid Classes = "unchecked" ColumnDefinitions = "Auto, Auto"> <Border Width = "20" Height = "20" Background = "Blue" CornerRadius = "5" /> <TextBlock FontWeight = "Bold" Margin = "5,0,0,0" Grid.Column = "1"> 0FF </TextBlock> </Grid> <Grid Classes = "checked" ColumnDefinitions = "Auto, Auto"> <Border Grid.Column = "1" Width = "20" Height = "20" Background = "Red" CornerRadius = "5" /> <TextBlock FontWeight = "Bold" Margin = "0,0,5,0"> ON </TextBlock> </Grid> </Grid> </Border> <Border Classes = "fade" Background = "White" CornerRadius = "5" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style Selector = "CheckBox.uberbox / template / Grid.checked"> <Setter Property = "Opacity" Value = "0" /> </Style> <Style Selector = "CheckBox.uberbox: checked / template / Grid.checked"> <Setter Property = "Opacity" Value = "1" /> </Style> <Style Selector = "CheckBox.uberbox: checked / template / Grid.unchecked"> <Setter Property = "Opacity" Value = "0" /> </Style> <Style Selector = "CheckBox.uberbox / template / Border.fade"> <Setter Property = "Opacity" Value = "0" /> </Style> <Style Selector = "CheckBox.uberbox: pointerover / template / Border.fade"> <Setter Property = "Opacity" Value = "0.2" /> </Style> </Window.Styles> <StackPanel> <CheckBox Classes = "uberbox" Margin = "10" /> </StackPanel>
Donde usar estilos
Los estilos se pueden usar tanto dentro de la ventana (como lo hicimos en los ejemplos escritos anteriormente),
y dentro de toda la aplicación (entonces el estilo se aplicará en todas las ventanas).
Para hacer esto, agregue el estilo al archivo
App.xaml <Application.Styles> <StyleInclude Source = "avares: //Avalonia.Themes.Default/DefaultTheme.xaml" /> <StyleInclude Source = "avares: //Avalonia.Themes.Default/Accents/BaseLight.xaml" /> <Style Selector = "Button"> <Setter Property = "Background" Value = "Blue"> </Setter> </Style> </Application.Styles>
Mayor separación
Con la complicación del código, ya no queremos mantener los estilos dentro del diseño de la ventana, sino que preferimos colocarlos en un archivo separado:

Para hacer esto, cree el directorio de Estilos y coloque nuestros estilos allí en forma de archivos xml o xaml, agregando el espacio de nombres:
<Styles xmlns = "https://github.com/avaloniaui" xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns: sys = "clr-namespace: System; assembly = netstandard"> <Style Selector = "Button / template / ContentPresenter"> <Setter Property = "CornerRadius" Value = "10" /> </Style> <Style Selector = "Button"> <Setter Property = "Foreground" Value = "# FFFFFFFF" /> <Setter Property = "BorderThickness" Value = "2" /> <Setter Property = "Background" Value = "# FFDD4812" /> <Setter Property = "BorderBrush" Value = "# FFFFFFFF" /> </Style> <Style Selector = "Button: pointerover / template / ContentPresenter"> <Setter Property = "BorderBrush" Value = "# FFDD4812" /> </Style> </Styles>
Agregue nuevos recursos al archivo del proyecto (* .csproj):
<AvaloniaResource Include = "Styles \ **" />
Y conéctelos usando la etiqueta
StyleInclude <Window.Styles> <StyleInclude Source = "/ Styles / Style.xml" /> </Window.Styles>
Pero a veces esto no es suficiente, y quiero poner los estilos en un dll separado para usar en todos mis proyectos.
Para hacer esto, cree una ClassLibrary y brinde soporte para nuestros archivos futuros como recurso disponible:
<ItemGroup> <AvaloniaResource Include="**\*.xaml"> <SubType>Designer</SubType> </AvaloniaResource> </ItemGroup> <ItemGroup> <AvaloniaResource Include="**\*.xml"> <SubType>Designer</SubType> </AvaloniaResource> </ItemGroup>
Ahora agregue el ya familiar Styles.xml y 2 archivos nuevos más al proyecto:

En el archivo xaml, debe especificar el espacio de nombres y la clase a la que pertenece, así como la conexión del recurso necesario:
<Styles xmlns = "https://github.com/avaloniaui" xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml" x: Class = "ClassLibrary1.DarkCustom"> <StyleInclude Source = "avares: //ClassLibrary1/Style.xml" /> </Styles>
Y en el archivo cs definimos que este es un estilo y no más:
namespace ClassLibrary1 { public class DarkCustom: Styles { } }
Agregue una dependencia a nuestra biblioteca y vuelva a conectar el estilo, especificando el estilo como un recurso de
avalonia usando
StyleInclude y
<Window.Styles> <StyleInclude Source = "avares: //ClassLibrary1/DarkCustom.xaml" /> </Window.Styles>
Algunas cosas más útiles
Asegúrese de revisar el Tutorial oficial de Avalonia Style (
aquí )
Puede obtener ideas básicas sobre cómo escribir un estilo para un elemento aquí (
aquí )
Y si no tiene el tiempo / deseo de crear su propio estilo, puede usar este maravilloso generador de estilos (
aquí )

Me gustaría decir gracias
ForNeVeR kekekeks worldbeater