乐于分享
好东西不私藏

手写一套 HMI 组态软件需要什么?.NET 8 + Avalonia 模块方案

手写一套 HMI 组态软件需要什么?.NET 8 + Avalonia 模块方案

前言

做上位机界面开发的朋友应该都清楚,从零搭建一套功能完整的可视化工具界面有多折腾——拖控件、绑数据、调通信、写脚本,每个环节都得自己撸一遍。

一套面向工业监控、设备管理、数据可视化场景的桌面端画面设计系统。这篇文章就聊聊它的整体思路、具体功能和我们实际落地时的考量。

项目介绍

项目本质上是一个所见即所得的画面设计器加运行时引擎,你可以把它理解成"工业级PPT + 脚本环境 + 通信网关"的混合体。它不像传统组态软件那样笨重,也不像通用UI框架那样需要写大量前端代码。

核心定位是:让实施人员通过拖拽配置就能完成大部分界面工作,遇到复杂逻辑时又能用C#脚本灵活兜底

整个工程基于.NET 8开发,渲染层用SkiaSharp保证跨平台一致性,脚本引擎走Roslyn动态编译,通信层支持Modbus、OPC UA、MQTT等主流协议。

项目功能

按实际使用流程把功能拆成八个模块,下面这张表可以快速看清全貌:

模块
核心能力
画面设计
多页面管理、图层分层、对齐辅助、网格吸附、批量操作
控件与插件
基础控件库(按钮/图表/仪表盘等)+ 插件化扩展机制
变量与数据
多类型变量管理、Excel导入导出、双向绑定、表达式运算
事件与脚本
C#脚本编辑器、断点调试、热重载、宿主API调用
工程与资源
多目录工程结构、增量保存、资源去重与引用溯源
预览与发布
实时预览、跨平台打包(Windows/Linux可执行画面包)
系统与主题
多语言切换、明暗主题、插件SDK、权限管理
通信与IO
驱动管理器、设备映射、数据采集队列、异常重连

项目特点

配置优先,脚本兜底:大部分交互逻辑通过数据绑定和表达式就能搞定,实在复杂的再上C#脚本,不至于把简单事情搞复杂。

插件化第一:从控件到通信驱动全部走插件加载,第三方集成时不用改主程序代码。

跨平台发布:一套工程既能出Windows版本也能出Linux版本,界面渲染保持一致。

调试体验友好:变量监控、脚本断点、通信报文收发都在一个环境里完成,不用来回切工具。

资源管理严谨:引用溯源和未使用标记功能避免工程膨胀,多人协作时减少冲突。

项目技术

技术项
选型与说明
运行时
.NET 6/8(跨平台支持)
渲染引擎
SkiaSharp(硬件加速,矢量渲染)
脚本引擎
Roslyn(动态编译,热重载)
数据绑定
自研属性绑定框架,支持双向同步
序列化
System.Text.Json(工程文件存储)
通信库
自研驱动适配层,封装Modbus/OPC UA/MQTT
本地数据库
SQLite(日志、报警、历史数据存储)
UI框架
Avalonia UI(跨平台原生界面)
插件架构
MEF(Managed Extensibility Framework)

项目代码(核心片段)

变量绑定与表达式求值的简化实现:

// 变量绑定核心:属性变化时同步更新绑定的变量publicclassBindingExpression{privatereadonlystring _expression;privatereadonly Dictionary<string, IVariable> _variables;publicobjectEvaluate()    {// 解析表达式中的变量占位符,如 [温度]var parsed = _expression.Replace("[""").Replace("]""");if (_variables.TryGetValue(parsed, outvarvar))        {// 如果是简单变量直接返回值returnvar.GetValue();        }// 如果是复杂表达式,调用内置函数库解析return ExpressionParser.Parse(_expression, _variables);    }}// 控件属性绑定示例:将按钮文本绑定到变量 "设备状态"var binding = new BindingExpression("[设备状态]", variableManager);button.TextBinding = binding;// 变量变化时自动刷新控件variableManager.OnVariableChanged += (name) => {if (name == "设备状态") button.Text = binding.Evaluate().ToString();};

插件加载机制的简化版本:

[Export(typeof(IControlPlugin))]publicclassGaugePlugin : IControlPlugin{publicstring DisplayName => "仪表盘";publicvoidRender(SKCanvas canvas, ControlProps props)    {// 使用SkiaSharp绘制刻度、指针和数值        DrawGauge(canvas, props.Value, props.Min, props.Max);    }public List<PropertyDescriptor> GetProperties()    {// 返回属性定义,自动映射到属性面板returnnew List<PropertyDescriptor> {new FloatProperty("MinValue"0),new FloatProperty("MaxValue"100),new IntProperty("TickCount"10)        };    }}

项目效果

通信稳定性方面,在Modbus TCP轮询100个寄存器、100ms间隔的场景下,CPU占用控制在5%以内,内存稳定在120MB左右。脚本热重载功能在现场调试时非常救命——修逻辑不用停运行中的画面,直接改完保存就能生效。

预览和发布的一致性做得比较到位,编辑时看到什么样,发布的exe跑起来就是什么样,没出现过"编辑时好好的,打包后变形"的情况。资源管理里的引用溯源功能帮我们清理了好几次历史遗留的未用图片,工程体积从800多MB降到了200多MB。

项目源码

总结

这套系统的初衷很简单——不想每次做项目都重复造界面和通信的轮子。从实际效果来看,配置驱动加脚本兜底的模式确实能兼顾效率和灵活性。技术选型上.NET生态的跨平台能力和Roslyn的脚本编译能力是两大支柱,SkiaSharp保证了一致的渲染表现。当然,不足也很明显:复杂动画的性能还有优化空间,表达式引擎目前不支持自定义函数扩展,这些是下一版本要补的短板。

如果大家是做设备监控、产线看板、数据中台前端这类工作,这套思路或许能给你一些参考。工具终究是工具,关键还是用对场景,我们不追求大而全,只求在工业界面这块领域里做得顺手、踏实。

关键词

画面设计器、数据绑定、C#脚本引擎、Roslyn编译、工业组态、Modbus通信、OPC UA、SkiaSharp渲染、插件化架构、变量监控、跨平台发布、表达式求值、热重载、MEF插件、Avalonia UI

最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

作者:小码编匠

出处:gitee.com/smallcore/DotNetCore
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!
END
推荐阅读
C# + OPC UA 的工业上位机 / HMI 组态平台(带拖拽设计器 + 运行态隔离)
一个PLC风格的上位机开发框架
WPF + MVVM 实现工业示波器界面与波形生成
一套现代化 WPF 控件生成器(附 16 款常用控件,一键导出可用的 DLL)

.NET 8 + Cursor 编写的工业 Web SCADA 系统

.NET 9.0 工业设备数据采集与监控平台

.NET 8 + WPF + Material Design 开发的工业传感器实时数据监控系统

.NET 8 + WPF 开发的工业设备日志 AI 分析工具

.NET 工业上位机20篇实战精选(SCADA/Modbus/视觉/运动控制)

.NET 8 开发的工业自动化上位机监控系统

WPF 搭建的现代化工业级数据采集与监控终端 (SCADA/HMI) 系统

.NET 技术栈全攻略后端、前端与部署运维

WPF + Modbus RTU 一套 SCADA监控系统的实现

WPF 工业级标签打印库,支持零件/二维码/条码自定义设计

WinForm 温湿度传感器数据采集与监控系统

工业上位机开发没头绪?这个 WPF 模板把 SCADA 和大屏都给整明白了

WPF + ONNX Runtime 实现 YOLOv5 目标检测桌面应用

C# 工控上位机必备:数据转换工具类与十个核心模块

.NET 9.0 全局键盘监听小工具,零依赖、双线程、低开销
一个轻量级、支持 MVVM 的高可定制开源 WPF 图表控件
WPF 工业数据采集系统,Modbus接入与公式计算
WinForms 无线环境监控上位机实战(滑动面板、仪表盘、定时存库)
WPF 工业上位机数据采集与监控系统(收藏版)
WPF + Modbus TCP 工业数据采集与实时监控系统
WinForm工业上位机工具库:从控件封装到 MES 对接的实战积累

WPF 一款轻量级多服务器远程管理工具,本地 JSON 存储,开箱即用

.NET 10 高性能、插件化的工业物联网通讯框架

C# 视觉检测平台(支持海康工业相机+OpenCV 算子流程编排+串口通信)

C# 实现 SCADA + 看板 + MES 接口,一套能落地的工业方案

.NET 8 工业自动化流程编辑器,不用写代码,拖拽生成PLC数据流

.NET 10 实现工业调试必备的通信工具(支持串口/Modbus/TCP/OPC UA)

WPF 工具 + 多模型 AI 代理让 Copilot 用上国产大模型

C# 高颜值工业设备监控上位机,支持多参数实时采集

觉得有收获?不妨分享让更多人受益

关注「DotNet技术匠」,共同提升技术实力

收藏
点赞
分享
在看