Net跨平台UI框架Avalonia入门-样式详解

设计器的使用

设计器预览

在window和usercontrol中,在代码中修改了控件,代码正确情况下,设计器中就可以实时看到变化,但是在样式(Styles)文件中,无法直接看到,需要使用设计器预览Design.PreviewWith标签

在这里插入图片描述

Design.PreviewWith中修改Border的Padding等属性设置预览区域大小,

  <Design.PreviewWith>
      <Border Width="500" Height="500" Padding="20">
          
      Border>
  Design.PreviewWith>

在Border内部添加需要预览的控件即可

Net跨平台UI框架Avalonia入门-样式详解_第1张图片

如果要预览多个控件,就跟在WPF中规则一样,先在Border加一个布局控件,然后在布局控件中随便放多少个都行

Net跨平台UI框架Avalonia入门-样式详解_第2张图片

绑定预览

在V11版本中,默认使用了mvvm模式,所以很多属性通过绑定实现,但是在开发过程中需要预览,则需要使用Design.DataContext标签,在里面放上对面的viewmodel。

 <Design.DataContext>
   
   <vm:MainViewModel />
 Design.DataContext>

需要注意:这个只是预览用,需要运行绑定则需要在别的地方设置

根据代码注释可以知道:这仅设置 IDE 中预览器的 DataContext,要设置运行时的实际 DataContext,请在代码中设置 DataContext 属性(查看app.axaml.cs)

在app.axaml.cs中设置
Net跨平台UI框架Avalonia入门-样式详解_第3张图片

样式、资源

样式、资源文件的定义和引用,见另一篇:Net跨平台UI框架Avalonia入门-资源和样式

样式

样式基础

一个样式基本的定义,使用Style定义样式,Setter定义具体的控件属性和值,然后通过选择器Selector来定义一个样式的名称。

样式使用,在控件通过Classes来使用样式

官方模版:

<Style Selector="selector syntax">
     "property name" Value="new value"/>
     ...
Style>

示例

<UserControl ....>
  <UserControl.Styles>
    <Style Selector="Button.btn1">
      "Background"  Value="Red"/>
    Style>
  UserControl.Styles>
  <Grid>
    <Button Classes="btn1" Content="12345"/>
  Grid>
UserControl>

效果:
Net跨平台UI框架Avalonia入门-样式详解_第4张图片

样式选择器(Selector)语法

avalonia样式中,使用Setter对属性和值的定义与WPF一样,选择器Selector更类似于CSS中使用的语法

1.选择器定义控件类型

Selector="ControlType(控件类型)" 表示在style应用范围里的这类控件都默认使用这个样式,控件不需要写Classes来使用样式

<Style Selector="Button">

示例:

 <UserControl ....>
 <UserControl.Styles>
   <Style Selector="Button">
     "Background"  Value="Red"/>
   Style>

 UserControl.Styles>
 <Grid>
   <Button Content="12345"/>
 Grid>
 UserControl>

Net跨平台UI框架Avalonia入门-样式详解_第5张图片

2.定义样式名称

在选择器中定义样式的名称Selector="ControlType(控件类型).Name(样式名称)",然后通过Classes来使用对应的样式


<Style Selector="Button.btn1">Style>

<Button Classes="btn1"/>

示例:

   <UserControl ....>
  <UserControl.Styles>
    <Style Selector="Button.btn1">
      "Background"  Value="Red"/>
    Style>

  UserControl.Styles>
  <Grid>
    <Button Classes="btn1" Content="12345"/>
  Grid>
UserControl>

Net跨平台UI框架Avalonia入门-样式详解_第6张图片

3.同时使用多个样式

Classes中通过空格分隔写多个样式名称

Classes="style1 style2"

示例:

<UserControl ...>
  <UserControl.Styles>
    <Style Selector="Button.btn1">
      "Background"  Value="Red"/>
    Style>

    <Style Selector="Button.btn2">
      "Foreground"  Value="White"/>
    Style>
  UserControl.Styles>
  <Grid>
    <Button Classes="btn1 btn2" Content="12345"/>
  Grid>
UserControl>

效果:

Net跨平台UI框架Avalonia入门-样式详解_第7张图片

4.交互状态效果的实现

控件悬停、按下、获取焦点等等特殊状态,在Avalonia中通过伪类(Pseudo Classes)来实现,伪类在选择器中的名称始终以冒号开头。

在Avalonia中可以用的相关伪类如下:

伪类 描述
:pointerover 指针输入当前悬停在(控件的边界内部)
:focus 控件拥有输入焦点
:disabled 控件无法响应用户交互
:pressed 按钮控件处于按下状态
:checked 复选框控件已选中(显示勾选标记)

有条件的也可以自己定义。Pseudo Classes

使用伪类定义样式

Selector中直接Selector="ControlType(控件类型):PseudoClasses(伪类)"Selector="ControlType(控件类型).Name(样式名称):PseudoClasses(伪类)"两种定义方式都可以,使用方式跟上面的一样,直接生效或者使用样式名称。

示例:

 <Style Selector="Border:pointerover">
      "Background" Value="Red"/>
  Style>
  
 <Style Selector="Border.bd1:pointerover">
   "Background"  Value="Red"/>
 Style>

效果:

Net跨平台UI框架Avalonia入门-样式详解_第8张图片

使用伪类的坑

1.Border必须有内容或者背景有初始化值,否则无法触发进入的效果,鼠标放在空白区域
Net跨平台UI框架Avalonia入门-样式详解_第9张图片

解决方案:

在样式中给属性添加默认值

注意:不能直接在控件上赋默认值,否则就无法触发

两种写法:

一种另写一个样式

 <Style Selector="Border">
   "Background"  Value="White"/>
 Style>
 <Style Selector="Border:pointerover">
   "Background"  Value="Red"/>
 Style>

效果:
Net跨平台UI框架Avalonia入门-样式详解_第10张图片

另一种:就是嵌套样式(在下面嵌套样式小节),效果一样

2.另一个坑就是其他控件,如Button,使用伪类直接改Button属性还是无效
如下,设置悬停颜色为红色,但是无效Net跨平台UI框架Avalonia入门-样式详解_第11张图片

这跟avalonia样式写法和工作原理有关,在下面选择器控制模版(template)里面的控件详细写

5.嵌套样式

在Style中定义一个Style,里面的Selector延续外面的Selector,使用^来替代上一级选择器的内容


    <Style Selector="Border">
      "Background"  Value="White"/>