教你用 Avalonia 实现工业水泵动画控件(含源码思路)

242 阅读4分钟

前言

随着国产化和跨平台开发需求的不断增长,越来越多的工业上位机应用开始从传统的 WinForm/WPF 向跨平台框架迁移。Avalonia 作为一款功能强大、兼容 WPF 语法的跨平台 UI 框架,正逐渐成为 .NET 开发的首选。

本文将带你使用 Avalonia 开发一个模拟水泵运行状态的自定义控件,重点讲解如何实现旋转动画、使用伪类控制状态,并分享开发过程中遇到的"坑"与解决方案,为工业可视化控件开发提供实用参考。

效果图

c43888292b872e5d0858377bbb1ec387_640_wx_fmt=gif&from=appmsg.gif

正文

在工业监控系统中,水泵、电机、风机等设备的动态状态展示是上位机界面的重要组成部分。通过动画直观地反映设备运行状态,不仅能提升用户体验,还能帮助操作人员快速判断系统工况。

本文以"水泵控件"为例,展示如何在 Avalonia 中实现一个具有旋转动画的可复用控件。

1、控件的构成

水泵控件的核心是一个中间可旋转的圆形部分,用于模拟水泵叶轮的运转。为了简化动画实现,我们使用一个 Canvas 容器将需要旋转的 Path 图形包裹起来。

这样,动画只需作用于 Canvas,避免了直接旋转 Path 时因坐标系问题难以确定旋转中心的复杂性。

以下是控件的核心 XAML 结构:

<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>

2、动画的创建

Avalonia 支持基于 CSS 样式的动画定义。我们通过伪类 running 来标识水泵的运行状态。动画的 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>
  • controls|Pump.running:选择 Pump 控件且处于 running 伪类状态。

  • ^ /template/ Canvas#BumpCircle:继承上层选择器,并进入控件模板内部,选择名为 BumpCircleCanvas

  • 动画从 0° 旋转到 360°,持续 5 秒,无限循环。

3、踩到的坑与解决方案

(1)自定义伪类的 Selector 写法

Avalonia 内置伪类如 :pointerover 使用冒号前缀,但自定义伪类在 Style Selector 中应直接使用点号连接,如 Pump.running,而非 Pump:running

(2)属性变更时动态更新伪类

最初尝试在 Running 属性的 set 方法中添加/移除伪类,但通过绑定(如 {Binding #CheckBox.IsChecked})更新属性时,set 方法不会被调用。

正确的做法是重写 OnPropertyChanged 方法,监听 RunningProperty 的变化:

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 简化动画实现、通过伪类管理控件状态、利用 OnPropertyChanged 响应属性变更。这些技巧不仅适用于水泵控件,也可推广至电机、阀门、传送带等其他动态工业控件的开发。Avalonia 的强大样式系统和跨平台能力,为构建现代化、高性能的工业上位机界面提供了坚实基础。希望本文能为大家的跨平台开发之旅提供有价值的参考。

关键词

Avalonia、跨平台开发、上位机、控件开发、水泵动画、旋转动画、伪类、OnPropertyChanged、Canvas、Selector、工业可视化

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者: 智汇IOT

出处:cnblogs.com/Cookies-Tang/p/18522958

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!