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”,原创技术文章第一时间推送。

Style Selector Syntax

How To Bind to a Contro

控件代码

Avalonia跨平台上位机控件开发之水泵的更多相关文章

  1. C# Winform开发以及控件开发的需要注意的,被人问怕了,都是基础常识

    我是搞控件开发的,经常被人问,所以把一些问题记录了下来!如果有人再问,直接把地址丢给他看. 一. 经常会有人抱怨Winform界面闪烁,下面有几个方法可以尽可能的避免出现闪烁 1.控件的使用尽量以纯色 ...

  2. C#ActiveX控件开发学习

    一:C#ActiveX控件开发注意事项   1:C#开发的ActiveX控件只可在装有Framework的系统上才能用. 2:只有IE浏览器支持. 3:初次安装需要导入代码签名证书及其证书链的方式, ...

  3. asp.net控件开发基础(1)(转)原文更多内容

    asp.net本身提供了很多控件,提供给我们这些比较懒惰的人使用,我认为控件的作用就在此,因为我们不想重复工作,所以要创建它,这个本身便是一个需求的关系,所以学习控件开发很有意思. wrox网站上有本 ...

  4. 利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

    Dixon 原文  用ArcGIS Engine.VS .NET和Windows控件开发GIS应用     此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署 ...

  5. Asp.Netserver控件开发的Grid实现(三)列编辑器

    以下是GridColumnsEditor的实现代码: GridColumnsEditor.cs using System; using System.Collections.Generic; usin ...

  6. ASP.NET2.0组件控件开发视频 初体验

    原文:ASP.NET2.0组件控件开发视频 初体验 ASP.NET2.0组件控件开发视频 初体验 录了视频,质量不是很好,大家体验下.我会重新录制的 如果不清楚,可以看看http://v.youku. ...

  7. ASP.NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  8. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...

  9. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl  后篇 --事件冒泡 系列文章链接: ASP.NET ...

  10. WinForm控件开发总结目录

    WinForm控件开发总结(一)------开篇 WinForm控件开发总结(二)------使用和调试自定义控件 WinForm控件开发总结(三)------认识WinForm控件常用的Attrib ...

随机推荐

  1. Vim 全局配置 / 设置鼠标模式

    新搞的 Linux (Debian) 上的 vim 一右击粘贴就变成 insert (Visual) 模式,上网查了一下,要 set mouse=,但是每次设置太麻烦了,另外我也想改一下全局配色. 定 ...

  2. PHP中的Malformed UTF-8 characters错误解决

    在PHP开发中,开发者经常会遇到Malformed UTF-8 characters错误.这个错误通常是由于代码中存在无效的UTF-8字符而引起的.本篇博客将为您介绍如何解决这个问题. 什么是UTF- ...

  3. MYSQL——mysql检索不包含字母U的数据

    2024/07/09 1. NOT LIKE 2. IS NOT.<>.!= 3. NOT IN 如题,正确答案如下: SELECT * FROM your_table_name WHER ...

  4. Zabbix监控可视化

    一.监控系统的架构体系 大家都知道,监控系统由三大部分组成,一,监控数据采集:二,监控告警分析:三,监控数据报表.可视化.在市面上常见的开源监控软件,或者商业监控软件中,均有很好的实践和体现. 监控系 ...

  5. 基于事件总线EventBus实现邮件推送功能

    有时候,有人给我的网站留了言,但是我必须要打开我的网站(https://www.xiandanplay.com/)才知道,所以我便决定给网站增加一个邮件推送的功能,好让我第一时间知道.于是乎,按照我自 ...

  6. C# 使用 PaddleOCRSharp 识别 图片中的文字、 使用QRCoder生成二维码

    目录 使用PaddleOCRSharp识别图片中的文字 PaddleOCRSharp资料汇总: 1.将源码编译成对应的.Net 版本引入到项目中 2. 初始化PaddleOCREngine 3. 调用 ...

  7. 使用广播星历计算卫星坐标(Python)

    前言 本代码为GNSS课程设计代码,仅供参考,使用的计算方法与公式均来源于王坚主编的<卫星定位原理与应用(第二版)>. 本代码计算结果可以通过下载精密星历进行比照,误差在1-10m左右. ...

  8. Vue SPA项目如何修改网站标题

    直接贴 门户项目代码 // 全局router 直接挂载路由导航守卫 router.beforeEach((to, from, next) => { if (to.meta.title) { va ...

  9. ES6中的Set数据结构

    Set是ES6新推出的数据结构,Set结构里面的每个元素都是唯一的: 如何创建一个Set? // Set 构造函数接收一个数组进行初始化;如果什么都不传则创建一个空Set; var set = new ...

  10. ES6之常用开发知识点:字符串的扩展与正则表达式的扩展(三)

    字符串的扩展 codePointAt JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2个字节.对于那些需要4个字节储存的字符(Unicode 码点大于0xFFFF的字符) ...