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

news2024/10/11 8:31:05

设计器的使用

设计器预览

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

在这里插入图片描述

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

  <Design.PreviewWith>
      <Border Width="500" Height="500" Padding="20">
          <!-- Add Controls for Previewer Here -->
      </Border>
  </Design.PreviewWith>

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

在这里插入图片描述

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

在这里插入图片描述

绑定预览

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

 <Design.DataContext>
   <!-- This only sets the DataContext for the previewer in an IDE,
        to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
   <vm:MainViewModel />
 </Design.DataContext>

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

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

在app.axaml.cs中设置
在这里插入图片描述

样式、资源

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

样式

样式基础

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

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

官方模版:

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

示例

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

效果:
在这里插入图片描述

样式选择器(Selector)语法

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

1.选择器定义控件类型

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

<Style Selector="Button">

示例:

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

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

在这里插入图片描述

2.定义样式名称

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

<!--定义-->
<Style Selector="Button.btn1"></Style>
<!--使用-->
<Button Classes="btn1"/>

示例:

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

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

在这里插入图片描述

3.同时使用多个样式

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

Classes="style1 style2"

示例:

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

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

效果:

在这里插入图片描述

4.交互状态效果的实现

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

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

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

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

使用伪类定义样式

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

示例:

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

效果:

在这里插入图片描述

使用伪类的坑

1.Border必须有内容或者背景有初始化值,否则无法触发进入的效果,鼠标放在空白区域
请添加图片描述

解决方案:

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

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

两种写法:

一种另写一个样式

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

效果:
请添加图片描述

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

2.另一个坑就是其他控件,如Button,使用伪类直接改Button属性还是无效
如下,设置悬停颜色为红色,但是无效请添加图片描述

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

5.嵌套样式

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


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

效果:

请添加图片描述

可以看到他的效果和跟下面分开两个样式的效果是一样的

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

6.样式增加属性条件

让样式在一定条件下生效,可以在Selector中增加[Property=value]来限制条件

示例:

  <UserControl ...>
  <UserControl.Styles>

    <Style Selector="Button[Content=12345]">
      <Setter Property="Background"  Value="Green"/>
    </Style>

    <Style Selector="Button.btn1[Content=123456]">
      <Setter Property="Background"  Value="Green"/>
    </Style>
  
  </UserControl.Styles>
  <StackPanel>
    <Button  Content="12345"/>
    <Button  Content="123"/>
    <Button Classes="btn1" Content="123456"/>
   
  </StackPanel>
</UserControl>

效果

在这里插入图片描述

7. 控制控件模板内部样式

Avalonia大部分控件都是继承于TemplatedControl控件,在默认的控件主题(ControlTheme)中定义了Template属性,有时候需要编写自己的样式,就需要直接操作Templae里面的控件。

并且在源码中很多伪类的样式,如pointeroverpressed等都的样式都已经定义了基本的样式,所以导致了上面定义Button之类的控件的伪类样式无效。
在这里插入图片描述

如果要进行Template里面一些控件样式的控制和修改(直接写了样式无法生效的情况),最好先有一份Avalonia的源码,照着源码改。下图就是一个button的源码(在Avalonia.Themes.Fluent项目的Controls文件夹下)。

在这里插入图片描述

Selector的写法Selector="控件类型:伪类 /template/ 内部控件的类型#内部控件的名称",如果内部控件类型唯一,可以不写内部控件的名称。

如下示例写了一个悬停变红的样式,如下几种写法都是正确的,跟之前几项语法可以自由组合

 <Style Selector="Button:pointerover /template/ ContentPresenter">
   <Setter Property="Background"  Value="Red"/>
 </Style>
    <Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresente">
     <Setter Property="Background"  Value="Red"/>
   </Style>
   
   <Style Selector="Button.btn1:pointerover /template/ ContentPresenter#PART_ContentPresenter">
     <Setter Property="Background"  Value="Red"/>
   </Style>

实现的效果:
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/993359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app 前面项目(vue)部署到本地win系统Nginx上

若依移动端的项目&#xff1a;整合了uview开源ui框架&#xff0c; 配置后端请求接口基本路径地址&#xff1a; 打包复现到nginx下&#xff1a; 安装个稳定版本的&#xff1a;nginx-1.24.0 部署配置&#xff1a; 增加了网站&#xff1a;8083端口的&#xff0c; 网站目录在ngi…

Reactor

1.epoll底层工作原理 creat: 红黑树 就绪队列 回调机制 control: 用户告诉内核做什么事情&#xff0c;就是操作红黑树 wait: 操作就绪队列 2.LT ET模式 3.Reactor 4.前摄式

懒汉式逆向APK

作者&#xff1a;果然翁 通过各方神仙文档,以及多天调试,整理了这篇极简反编译apk的文档(没几个字,吧).轻轻松松对一个apk(没壳的)进行逆向分析以及调试.其实主要就是4个命令. 准备 下载apktool &#xff1a;https://ibotpeaches.github.io/Apktool/install/下载Android SDK …

被问到: http 协议和 https 协议的区别怎么办?别慌,这篇文章给你答案

前言 作为软件测试师&#xff0c;大家都知道一些常用的网络协议是我们必须要了解和掌握的&#xff0c;比如 HTTP 协议&#xff0c;HTTPS 协议就是两个使用非常广泛的协议&#xff0c;所以也是面试官问的面试的时候问的比较多的两个协议&#xff1b;因为这两个协议有相似和关联的…

CSP 202209-1 如此编码

答题 题目就是字多 #include<iostream>using namespace std;int main() {int n,m;cin>>n>>m;int a[n],c[n1];c[0]1;for(int i0;i<n;i){cin>>a[i];c[i1]c[i]*a[i];}for(int i0;i<n;i){cout<<(m%c[i1]-m%c[i])/c[i]<< ;} }

基于 Flink CDC 高效构建入湖通道

摘要&#xff1a;本文整理自阿里云 Flink 数据通道负责人、Flink CDC 开源社区负责人&#xff0c; Apache Flink PMC Member & Committer 徐榜江&#xff08;雪尽&#xff09;&#xff0c;在 Streaming Lakehouse Meetup 的分享。内容主要分为四个部分&#xff1a; 1. Flin…

2.4 选择结构语句

选择结构语句根据是否满足某个条件确定执行哪些操作&#xff0c;分为if条件语句和switch条件语句。 1. 单分支if语句 &#xff08;1&#xff09;if语句是指如果满足某种条件&#xff0c;就进行某种处理&#xff0c;格式如下。 if(条件) {// 执行语句 } 根据上述格式中&…

有限状态机的概念

一、有限状态机的概念 有限状态机简称状态机&#xff0c;是表示有限个状态&#xff0c;以及在状态之间的转移和动作等行为的数学模型。状态机的要素有状态和状态转移两个。 在Unity中&#xff0c;动画状态机最重要的属性就是节点和连线&#xff0c;其中每个节点都是一个动画片…

zotero的使用教程

1. zotero安装 1.1 下载 官网下载地址:Zotero 1.2 安装 建议自定义安装路径,不要安装在C盘。如以下步骤: 2. 插件安装 一般安装以下四种插件,即茉莉花(Jasminum)、zotfile、zotero-scihub、zotero-pdf-translate。以安装茉莉花插件为例进行说明,如图1所示,其余插件安…

Linux mac Windows三系统 局域网文件共享方法

主要工具&#xff1a; Samba是一个开源的软件套件&#xff0c;允许Linux系统与Windows系统之间共享文件和打印机。 一、首先是Linux共享的设置 ①安装 sudo apt-get install samba ②创建共享文件夹 sudo mkdir /home/share ③配置用户 sudo smbpasswd -a kequan ④修改…

软件测评的必要性,第三方软件测试机构推荐

软件测评报告 1、什么是软件测评报告&#xff1f; 测试报告是指把测试的过程和结果写成文档&#xff0c;对发现的问题和缺陷进行分析&#xff0c;为纠正软件的存在的质量问题提供依据&#xff0c;同时为软件验收和交付打下基础。 2、软件测评报告的作用 一份详细的测试报告…

git打tag和版本控制规范

我们在开发中经常会遇到要打tag的情况&#xff0c;但这个tag应该如何打呢&#xff1f;我不知道大家平时是怎么打的&#xff0c;但我基本就是从1.0.0开始进行往上递增&#xff0c;至于如何递增&#xff0c;基本凭感觉。今天同事新打了一个tag进行发版&#xff0c;然后被架构点名…

计算机竞赛 基于深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …

AJAX学习总结+Axios异步框架+Filter拦截器学习+JSON介绍+Listener监听器介绍

壹、AJAX 一、AJAX介绍 AJAX&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff1a;异步的JavaScript和XML AJAX作用&#xff1a; 1. 与服务器进行数据交换&#xff1a;通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据。&#xff08;原先…

过于依赖性的危机:探索品牌代理商背后的实质含义

据IDC中国报道称&#xff1a;2023年中国低代码与零代码软件市场规模将达到34.7亿元人民币&#xff0c;同比增长32.4%。预计到2027年市场规模将达到106.3亿元人民币&#xff0c;未来5年市场年复合增长率&#xff08;CAGR&#xff09;为32.3%。 随低代码市场规模不断扩大&#xf…

【计算机网络】 确认应答机制与超时重传

文章目录 ACK机制——确认应答机制超时重传 ACK机制——确认应答机制 当我们客户端发送了一个数据&#xff0c;seq是1100&#xff0c;那么服务端在收到时就会回一个ack101的ACK包&#xff0c;代表101之前的包我都收到了&#xff0c;下面请你从101继续发送。然后客户端就会发送1…

无涯教程-JavaScript - IMARGUMENT函数

描述 IMARGUMENT函数返回参数$\theta $(theta),以弧度表示的Angular,如- $$x yi \left | x yi \right | e ^ {i \theta} \left | x yi \right |(\cos \theta \sin \theta)$$ 语法 IMARGUMENT (inumber)争论 Argument描述Required/OptionalInumberA complex number f…

【C++基础】7. 控制语句

文章目录 【 1. 循环 】1.1 循环类型1.2 循环控制语句break 语句continue 语句goto 语句 1.3 无限循环 【 2. 选择 】switch 语句&#xff1f;&#xff1a;语句 【 1. 循环 】 1.1 循环类型 循环类型描述while 循环当给定条件为真时&#xff0c;重复语句或语句组。它会在执行…

floodfill算法(洪水灌溉算法)

一)floodfill算法简介: 二)图像渲染 733. 图像渲染 - 力扣&#xff08;LeetCode&#xff09; class Solution {int[] dx {1, 0, 0, -1};int[] dy {0, 1, -1, 0};//上下搜索的时候要使用向量数组int row0;int col0;int target0;public void dfs(int[][] image,int i,int j,int…

认识模块化

1. 模块化的基本概念 1.1 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组 合、分解和更换的单元。 1. 现实生活中的模块化 2.编程领域中的模块化 编程领域中的模块化&#xff0c;…