隨著社會的發(fā)展,大家對軟件的要求,從最初的命令行輸入輸出,到可視化輸入輸出,如報表,圖表等;從最初的可用性,穩(wěn)定性為主,到現(xiàn)代軟件理念中的便捷易用性轉(zhuǎn)變,在保證穩(wěn)定可用外,對軟件的交互易用要求越來越高,而這些則離不開UI設計以及樣式的應用。今天以一些簡單的小例子,簡述Avalonia UI中樣式與主題的應用,僅供學習分享使用,如有不足之處,還請指正。 樣式概述Avalonia UI中的樣式是一種可以在控件之間共享屬性設置的機制。與WPF中的樣式不同,Avalonia UI中的樣式設置借鑒了B/S開發(fā)中的CSS樣式理念;不過Avalonia UI引入了主題(ControlTheme)和WPF中的樣式相對應。當給UI控件設置樣式時,樣式系統(tǒng)從控件開始沿著邏輯樹向上搜索,直到應用程序的最高級別(App.axaml)。如果樣式系統(tǒng)匹配到控件設置的樣式時,則根據(jù)樣式中的設置器互進行更改。樣式系統(tǒng)沿著邏輯樹向上搜索,采用就近原則,所以如果有多個匹配項,則離控件更近的地方定義的樣式可以覆蓋離控件較遠的地方定義的樣式。樣式定義樣式的定義包含兩部分:選擇器屬性(Selector)和一個或多個設置器元素(Setter)。選擇器的值包含使用Avalonia UI“樣式選擇器語法”的字符串。每個設置器元素通過名稱標識將被更改的屬性和將被替換的新值。語法如下:<Style Selector="selector syntax"> <Setter Property="property name" Value="new value"/> ... </Style> 說明:Avalonia UI 樣式選擇器語法 類似于 CSS(層疊樣式表)中使用的語法。樣式放置在UserControl或Window或者Application上的Styles集合中,如下所示:<UserControl.Styles> <Style Selector="Button"> <Setter Property="Background" Value="Red"></Setter> <Setter Property="Margin" Value="10"></Setter> </Style> </UserControl.Styles> <StackPanel> <Button Width="100" Height="100" Content="按鈕"></Button> <Button Width="100" Height="100" Content="按鈕"></Button> </StackPanel> 上述樣式示例,定義了一個Button按鈕的樣式(背景色為紅色,邊距為10px),選擇器屬性為Button,表示在UserControl范圍內(nèi)的Button都會應用此樣式,如StackPanel中的Button,示例效果如下所示:選擇器定義樣式將作用與哪些控件,定義選擇器的格式有很多種,類型選擇器是比較常用的一種方式。設置器描述了當選擇器與控件匹配時會發(fā)生什么,設置器主要設置控件的屬性Property和值Value。當樣式與控件匹配時,樣式中所有的設置器都將應用于控件。樣式嵌套在實際應用中,除了可以定義單獨的樣式,還可以定義嵌套樣式,而嵌套樣式只需要將子樣式作為Style元素的子元素包含,并在子選擇器的開頭加上“嵌套選擇器標識符^”。如下所示:<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas./markup-compatibility/2006" xmlns:vm="clr-namespace:FirstAvalonia.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="FirstAvalonia.Views.MainView"> <UserControl.Styles> <Style Selector="TextBlock.h1"> <Setter Property="FontSize" Value="24"/> <Setter Property="FontWeight" Value="Bold"/>
<Style Selector="^:pointerover"> <Setter Property="Foreground" Value="Red"/> </Style> </Style> </UserControl.Styles> <StackPanel> <TextBlock Classes="h1" Text="字號24,加粗,鼠標放上變紅色"></TextBlock> </StackPanel> </UserControl> 在上述示例中,子樣式繼承了父樣式的屬性設置,當鼠標懸停在TextBlock.h1設置的樣式時,子樣式才會生效。如下:注意,"嵌套選擇器標識符^"必須存在,并且必須出現(xiàn)在子選擇器的開頭樣式鍵樣式選擇器匹配的對象的類型并不是由控件的具體類型決定的,而是通過檢查器StyleKey屬性來確定。默認情況下,StyleKey屬性返回當前實例的類型。示例:當你自定義一個控件,且它繼承自Button,如果你希望它被樣式化一個按鈕,可以重寫StyleKeyOverride屬性,并讓它返回typeof(Button)。如下所示:public class MyButton : Button { // MyButton 將會被作為標準的 Button 控件樣式化。 protected override Type StyleKeyOverride => typeof(Button); } 在WPF/UWP中,當你派生一個新的控件時,它將被樣式化為其基礎控件,除非你覆蓋了DefaultStyleKey屬性。在Avalonia UI中,控件將使用其具體類型進行樣式化,除非提供了相同的樣式鍵。樣式類在Avalonia UI中,可以為控件分配一個或多個樣式類,并使用它們來指導樣式選擇。樣式類通過在控件元素中使用Classes屬性進行分配。多個樣式類之間用空格進行分隔。示例如下所示:<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas./markup-compatibility/2006" xmlns:vm="clr-namespace:FirstAvalonia.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="FirstAvalonia.Views.MainView"> <UserControl.Styles> <Style Selector="Button.h1"> <Setter Property="FontSize" Value="24"></Setter> </Style> <Style Selector="Button.blue"> <Setter Property="Background" Value="Blue"></Setter> </Style> </UserControl.Styles> <StackPanel> <Button Classes="h1 blue" Width="100" Height="100" Content="按鈕"></Button> <Button Width="100" Height="100" Content="按鈕"></Button> </StackPanel> </UserControl> 在上述示例中,第一個Button應用了h1,blue兩個樣式,第二個按鈕沒有應用樣式,差別如下:注意,選擇器中樣式類的定義必須以“控件類型.樣式類名稱”的格式進行定義。多個樣式類定義必須用點號分隔,如“Button.larger.blue”等。如果選擇器指定了多個類,則控件必須同時擁有所有請求的類定義才能匹配。偽類偽類(Pseudo Classes)與CSS類似,控件可以擁有偽類,這些類是控件本身而不是用戶定義的。偽類在選擇器中的名稱,始終以“冒號”開頭。如:pointerover偽類表示鼠標懸停在控件上,pressed偽類表示鼠標在按鈕上按下,checked表示復選框選中時。示例如下所示:<StackPanel> <StackPanel.Styles> <Style Selector="Border:pointerover"> <Setter Property="Background" Value="Red"/> </Style> </StackPanel.Styles> <Border> <TextBlock>I will have red background when hovered.</TextBlock> </Border> </StackPanel>
控件主題控件主題是在樣式的基礎上構建的,用于為控件創(chuàng)建可切換的主題??丶黝}本質(zhì)是樣式,但和樣式有一些區(qū)別:- 控件主題沒有選擇器,它們有一個TargetType屬性,用于描述它們要針對的控件。
- 控件主題存儲在ResourceDictionary中,而不是Styles集合中。
- 控件主題通過設置Theme屬性來分配給控件,通常使用StaticResource標記擴展。
控件主題通常用于模板化控件,對于非模板化的控件,通常使用標準樣式更方便。定義主題,控件主題作為資源的形式出現(xiàn),一般可以在窗口(Window),用戶控件(UserControl),應用程序(Application)的Resources中進行定義,如下所示:<Application xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="FirstAvalonia.App" RequestedThemeVariant="Default"> <Application.Styles> <FluentTheme /> </Application.Styles> <Application.Resources> <ControlTheme x:Key="EllipseButton" TargetType="Button"> <Setter Property="Background" Value="Blue"/> <Setter Property="Foreground" Value="Yellow"/> <Setter Property="Padding" Value="8"/> <Setter Property="Template"> <ControlTemplate> <Panel> <Ellipse Fill="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> <ContentPresenter x:Name="PART_ContentPresenter" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" VerticalAlignment="Center" HorizontalAlignment="Center" /> </Panel> </ControlTemplate> </Setter> </ControlTheme> </Application.Resources> </Application> 在上述示例中,ControlTheme作為Resources的子元素,x:Key表示資源的唯一標識,TargetType表示主題要應用的控件類型。應用主題,主題定義完成后,可以在控件上通過Theme="{StaticResource ResourceKey}"的形式進行引用,如下所示:<StackPanel Orientation="Horizontal"> <Button Classes="h1 blue" Width="100" Height="100" Content="按鈕" Theme="{StaticResource EllipseButton}"></Button> <Button Width="100" Height="100" Content="按鈕" ></Button> </StackPanel>
控件主題查找如果控件的Theme屬性被設置,則應用該控件主題;如果沒有指定控件的Theme屬性,Avalonia UI會從邏輯樹向上搜索控件,查找一個x:Key與控件的樣式鍵匹配的ControlTheme資源。所以就有兩種方式來定義控件主題:- 如果希望控件主題應用于控件的所有實例,則將主題資源的x:Key屬性設置為{x:Type}作為資源的標識,如:<ControlTheme x:Key="{x:Type Button}" TargetType="Button">。
- 如果希望控件主題應用于選定的控件實例,則需要使用普通文本內(nèi)容作為資源鍵,并使用StaticResource查找資源。
ControlTheme中的TargetType屬性指定適用于Setter屬性的類型。如果沒有指定TargetType,則必須使用類名限定Setter對象中的屬性,使用Property="ClassName.Property" 的語法。以上就是《Avalonia系列文章之樣式與主題》的全部內(nèi)容,關于更多詳細內(nèi)容,可參考官方文檔。希望能夠一起學習,共同進步。學習編程,從關注【老碼識途】開始,為大家分享更多文章!?。?/span> 
|