Avalonia跨平台上位机控件开发之水泵
Avalonia跨平台上位机控件开发之水泵
随着国产化的推进,越来越多的开发者选择使用跨平台的框架来创建上位机应用,而Avalonia正是一个优秀的选择。本文将探讨如何利用Avalonia框架进行水泵控件的开发,并重点记录在开发的过程中所碰到的一些问题。
控件的构成
水泵控件主要在控件的内部需要创建一个旋转的动画来表示水泵当前的运行状态,在没有工作时为静止状态没有任何动画,当水泵启动时会对中间的部分进行连续的旋转。运行效果如下:

动画的创建
在控件中为了方便控制旋转动画的编写,我这边使用了一个Canvas将需要旋转的部分包裹在其中,这样在制作动画的时候直接对这个Canvas进行旋转就可以了,否则要旋转部分的Path的坐标数据为相对于最外层Canvas的坐标进行绘制,此时要找到旋转中心是一个很困难的事情。同时为这个Canvas指定了一个名称,方便后续在制作动画时的Selector处理。
<Canvas
Canvas.Left="19.5"
Canvas.Top="39.5"
Height="34.5"
Name="BumpCircle"
UseLayoutRounding="False"
Width="34.2">
<Path
Fill="#ffffffff"
Stroke="#ff6c6c6c"
StrokeJoin="Miter"
StrokeThickness="2.05166">
<Path.Data>
<PathGeometry Figures="M 11.3573 15.4557 C 6.78011 13.3704 4.04416 9.6096 3.14943 4.1733 M 11.3573 19.7314 C 6.82241 21.3797 2.37649 20.6383 -1.98048 17.5071 M 15.4612 22.6354 C 13.3753 27.2112 9.61334 29.9464 4.17541 30.8408 M 19.7381 22.6354 c 1.64889 4.53351 0.907239 8.97809 -2.22494 13.3338 m 5.12991 -17.4365 c 4.57717 2.08531 7.31313 5.84611 8.20786 11.2824 M 22.6431 14.2571 c 4.53487 -1.64839 8.98079 -0.906966 13.3378 2.22428 M 18.5392 11.353 c 2.08594 -4.5758 5.84787 -7.31093 11.2858 -8.20539 m -15.5627 8.20539 c -1.64889 -4.53351 -0.907239 -8.97809 2.22494 -13.3338 m 4.50314 14.9864 c 2.20369 2.20302 2.20369 5.77484 0 7.97786 c -2.20369 2.20302 -5.77658 2.20302 -7.98027 0 c -2.20369 -2.20302 -2.20369 -5.77484 0 -7.97786 c 2.20369 -2.20302 5.77658 -2.20302 7.98027 0 m 9.43124 -9.4284 c 7.41241 7.41018 7.41241 19.4245 0 26.8347 c -7.41241 7.41019 -19.4304 7.41019 -26.8428 0 c -7.41241 -7.41018 -7.41241 -19.4245 0 -26.8347 c 7.41241 -7.41019 19.4304 -7.41019 26.8428 0" />
</Path.Data>
</Path>
</Canvas>
动画的部分定义了一个伪类running,用来表示当前水泵已经处在了运行状态。因此在进行动画编写的时候先使用一下Selector选择伪类为running
<Style Selector="controls|Pump.running">
然后需要选择到我们需要需要进行动画的部分,使用如下的Selector进行选择
<Style Selector="^ /template/ Canvas#BumpCircle">
^ : 继承上一层Selector
/template/ :进入到控件内部的Template
Canvas#BumpCircle:选择名字为BumpCircle的Canvas
使用Selector选择到需要动画的控件部分后就可以进行动画的编写,动画的完整代码如下:
<Style Selector="controls|Pump.running">
<Style Selector="^ /template/ Canvas#BumpCircle">
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="INFINITE">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Style>
以上代码创建了一个0到360度的旋转动画。
踩到的坑
创建伪类时的一个小知识点
当在avalonia中使用伪类的时候经常会碰到:pointerover等内置的一些伪类,而要使用Selector来选择这些伪类的时候通常我们会使用
<Style Selector="Button:pointerover"/>
但是当我们定义了一个自定义的伪类时,比如上面控件用到的running,此时我们在使用Selector的时候需要使用如下格式
<Style Selector="Pump.running"/>
在平时的开发中要注意以上的一些不同
在属性改变时为控件添加伪类
为了表示控件的运行状态,我在控件的C#代码中添加了一个名为Running的StyledProperty,用这个属性来区分水泵的运行状态,因此我需要在Running属性进行修改的时候为控件添加或移除running伪类。而为了方便测试我将这个Running绑定至了Checkbox的IsChecked属性,代码如下:
<CheckBox
Canvas.Left="600"
Canvas.Top="250"
Name="CheckBox">
运行状态
</CheckBox>
<controls:Pump
Canvas.Left="600"
Canvas.Top="100"
Height="100"
Running="{Binding #CheckBox.IsChecked}"
Width="100" />
开始时我将伪类的创建与移除代码编写在Runing属性的set中进行处理,代码如下:
public bool? Running
{
get => GetValue(RunningProperty);
set
{
SetValue(RunningProperty, value);
if (value == true)
{
PseudoClasses.Add("running");
}
else
{
PseudoClasses.Remove("running");
}
}
}
但是以上的代码在CheckBox的IsChecked属性变更时并没有办法触发到set方法,导致动画无法被触发。
经过一段时间的摸索正确的做法为在OnPropertyChanged方法中进行相关的处理,代码如下:
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == RunningProperty)
{
if (change.NewValue != null && (bool)change.NewValue)
{
PseudoClasses.Add("running");
}
else
{
PseudoClasses.Remove("running");
}
}
}
总结
在本文中,我们探讨了如何利用Avalonia框架开发水泵控件,并详细介绍了控件构成、动画创建及开发过程中的一些问题和解决方案。通过使用Canvas包裹可旋转部分,我们简化了动画实现,同时利用伪类管理水泵的运行状态,使得控件的交互性和视觉效果得到了有效提升。
我们还分享了在创建自定义伪类时的一些注意事项,以及如何在属性变更时动态更新伪类的实现。这个过程强调了Avalonia框架在构建灵活、跨平台的用户界面方面的强大能力。
希望这篇文章能够为开发者在使用Avalonia进行控件开发时提供一些实用的参考和启发,助力他们更好地实现工业自动化中的各类应用。无论是初学者还是经验丰富的开发者,都可以在这个过程中获得新的见解和技巧。让我们共同期待在Avalonia上实现更多的创意与创新!
控件的完整代码由于内容较多,请至文章底部的控件代码链接自行获取。
欢迎关注我的公众号“nodered-co”,原创技术文章第一时间推送。

Avalonia跨平台上位机控件开发之水泵的更多相关文章
- C# Winform开发以及控件开发的需要注意的,被人问怕了,都是基础常识
我是搞控件开发的,经常被人问,所以把一些问题记录了下来!如果有人再问,直接把地址丢给他看. 一. 经常会有人抱怨Winform界面闪烁,下面有几个方法可以尽可能的避免出现闪烁 1.控件的使用尽量以纯色 ...
- C#ActiveX控件开发学习
一:C#ActiveX控件开发注意事项 1:C#开发的ActiveX控件只可在装有Framework的系统上才能用. 2:只有IE浏览器支持. 3:初次安装需要导入代码签名证书及其证书链的方式, ...
- asp.net控件开发基础(1)(转)原文更多内容
asp.net本身提供了很多控件,提供给我们这些比较懒惰的人使用,我认为控件的作用就在此,因为我们不想重复工作,所以要创建它,这个本身便是一个需求的关系,所以学习控件开发很有意思. wrox网站上有本 ...
- 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用
Dixon 原文 用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署 ...
- Asp.Netserver控件开发的Grid实现(三)列编辑器
以下是GridColumnsEditor的实现代码: GridColumnsEditor.cs using System; using System.Collections.Generic; usin ...
- ASP.NET2.0组件控件开发视频 初体验
原文:ASP.NET2.0组件控件开发视频 初体验 ASP.NET2.0组件控件开发视频 初体验 录了视频,质量不是很好,大家体验下.我会重新录制的 如果不清楚,可以看看http://v.youku. ...
- ASP.NET自定义控件组件开发 第五章 模板控件开发
原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...
- ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡
原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl 后篇 --事件冒泡 系列文章链接: ASP.NET ...
- WinForm控件开发总结目录
WinForm控件开发总结(一)------开篇 WinForm控件开发总结(二)------使用和调试自定义控件 WinForm控件开发总结(三)------认识WinForm控件常用的Attrib ...
随机推荐
- Spring启动报8080端口被占用问题
1.window下关闭8080端口 win+R:输入cmd,回车 在黑窗口中输入指令:netstat -ano | findstr 8080 指令的意思是找出占用8080端口的进程pid ...
- Java学习笔记1--JDK,JRE和JVM
1.Java开发环境 Java开发环境是指Java程序员开发.编写.测试和调试Java程序所使用的所有工具和技术.Java开发环境通常由以下几个部分组成: JDK(Java Development K ...
- idea汉化包安装失败解决方法
idea安装中文插件时提示: Plugin "Chinese (Simplified) Language Pack / 中文语言包" was not installed: 查看自己 ...
- 微服务全链路跟踪:grpc集成jaeger
微服务全链路跟踪:grpc集成zipkin 微服务全链路跟踪:grpc集成jaeger 微服务全链路跟踪:springcloud集成jaeger 微服务全链路跟踪:jaeger集成istio,并兼容u ...
- Linux下SPI驱动详解
更多嵌入式原创文章,请关注公众号:一口Linux 1. SPI总线 1.1. SPI总线概述 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口. ...
- manim 中的三维视角
今天研究了一下 manim 中的 ThreeDAxes 和 set_camera_orientation 这里记录一下视角. manim 中的 3D 坐标系是笛卡尔的三维坐标系,属于右手坐标系,即右手 ...
- Linux CentOS 7 安装 Kafka 2.8.2 - 单机版 & JDK 11 & 切换 JDK版本
目录 安装 JDK 11 安装 Kafka 下载 Kafka 2.8.2 防火墙 修改配置 运行测试 自启动 验证端口 Kafka 从 2.6.0 开始,默认使用 Java 11 , 3.0.0 开始 ...
- C++ 中string,wstring,CString常用方法
一.概念 string和CString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中.wstring是操作宽字符串的类.C++标准程序库对于string的设 ...
- C# 读取DBF文件到Datatable
此种方式不依赖与任何驱动,第三方插件. 核心代码TDbfTable如下: using System; using System.Collections.Generic; using System.Te ...
- Docker 构建多平台镜像
构建多平台镜像的方法分为两种:一种是在不同平台的机器上分别构建并推送对应平台的镜像,然后通过 Docker Manifest 将两个镜像标签合并为一个.另一种是通过 Docker buildx 在一台 ...