当前位置: 首页 > news >正文

C#+WPF上位机开发(模块化+反应式)

在上位机开发领域中,C#与C++两种语言是应用最多的两种开发语言,在C++语言中,与之搭配的前端框架通常以QT最为常用,而C#语言中,与之搭配的前端框架是Winform和WPF两种框架。今天我们主要讨论一下C#和WPF这一对组合在上位机开发过程中的实际应用。

在这里插入图片描述

一、模块化概念

开发一套完善的软件,离不开良好的架构,而说到架构,在C#中,Prism框架与WPF的配合可谓大大提高了开发效率,原因如下:Prism框架中有IOC容器(分别是unity和dryioc),IOC容器负责管理类的生命周期;另外,Prism框架的WPF版本还有区域管理器(RegionManager)、事件聚合器(EventAggregator),对话框服务(DialogService)、适配器(Adapter)、模块管理器(ModuleManager)等。

除了模块管理器(IModule接口),其他几个重要的管理器都是为了更方便实现界面呈现及业务逻辑开发,那么模块管理器的功能是什么呢?程序员往往会将一个大型的软件项目拆分成小项目(模块),比如上位机系统中会接入各种硬件(工业相机、PLC、数据采集器、扫码枪、控制卡等),良好的软件架构思路是将同一种类型的硬件抽象成一个硬件抽象类,然后,不同型号的硬件与继承这个抽象基类,实现各自硬件的业务逻辑(加载硬件、打开硬件、使用硬件、关闭硬件),要实现这些开发,Prism的模块就派上用场了。也就是将硬件进行模块化,由Prism框架去实现及统一管理。

当然,除了上述的例子,软件的基础库,软件的业务逻辑,同样可以拆成不同的模块,最后由Prism框架统一管理。

二、反应式概念

C#语言为我们提供了一个IObservable接口,也就是设计模式中的观察者模式在C#语言中的具体实现。ReactiveUI框架对此接口进行了扩展,使之变得易用。

在传统的软件开发中,我们对某个属性发生变化后要进行下一步的相应处理时,会主动对判断这个属性的值,然后实现相应的代码逻辑。而在观察者模式下,我们会写一个观察者,由这个观察者去“实时”观察这个属性,一旦观察到属性值发生了改变,会抛出一个通知。

那么,通知谁呢?

谁去订阅了这个观察者,其回调函数都会被触发一次调用,从而达到一个目的,即被观察的那个属性发生改变后会执行事先写好的“某一段代码逻辑”。

这样的开发模式在写上位机软件时非常可靠和易用,因为上位机可能会实时监测下位机的某些参数变化,一旦硬件参数发生变化,软件要相应给出动作(做出反应),这种反应,我们称为反应式编程。

三、软件架构

良好的架构,可以帮助开发人员提高开发效率,减少bug的发生,增强系统的稳定性。我们可以将一个上位机系统分成如下几个方面:

第一是具有通用性的基础类库,这一些类与具体的业务逻辑无关,只帮助处理业务过程中的数据,通常是一些帮助类,或者语言包,本地设置等等;

第二、是硬件模块,上位机开发离不开硬件的接入,而不同的上位机系统,其接入的硬件也是五花入门,比如MES系统,可能最常见的硬件是PLC、扫码枪;而控制系统,则控制卡与各种被控设备的信息反馈最为常见;AOI,AXI等工业视觉检测方面,则接入的硬件除了PLC和控制卡,还有工业相机,光机,光源等等;或者医学方机的上位机,包含了更多的非标设备。

如此多的硬件,如何有序的接入到上位机呢?

答案是,最好将同一种类型的硬件抽象成一个基类,通过接口、抽象类、继承等方面的编程手段,为每一种不同厂家或不同型号的硬件创建一个项目,将这些项目看成是一个个独立的模块,像小孩子玩积木游戏一般,将硬件“堆积”到上位机中,一旦某个型号的硬件想被替换,直接将新硬件的模块加载到上位机即可。

第三,是数据库模块。由于上位机系统运行过程中需要处理大量的数据,其处理结果需要持久化,一般采用文件或数据库的形式进行保存。而数据库的操作就可以单独形成一个模块,这个模块包含抽象类模块和具体的数据库操作类模块,因为最终要保存的数据库可能是mysql、oracle、mssql等不同的数据库,所以最好的方式是为不同类型的数据库的增删改查等操作开发各自的模块,以便管理和替换。

第四,是业务逻辑模块。这一类型的模块会随着不同行业的上位机功能需求,模块的多少会有所不同。尽量将复杂的业务逻辑拆分成独立的小型业务模块,模块与模块之间采用接口通讯,这样做的好处是:减少代码间的耦合程度,尽量开发一些职责单一的类,达到具有良好扩展性的代码架构。
在这里插入图片描述
四、详细设计

在聊完了大致的软件架构,我们来谈谈具体的模块设计。利用vs2022开发软件,一个模块就是一个项目,有的项目是类库,有的是用户控件,有的是窗体,还有的是C++项目,具体的开发如下所示:

为了更清晰明了每个项目的含义,我们制定一套项目(模块)的命名规则:公司名+架构分类名+模块名,比如Company.Application.Main,表示应用层的主模块。

第一、程序入口项目

Company.Application.Shell,这是上位机系统的入口,其实是一个窗体,启动时加载的第一个窗体,其内容由主模块进行填充。

第二、应用层模块

Company.Application.Main,这是上位机的主模块,由Prism框架的区域管理器将此模块导航到Shell窗体中。

Company.Application.Config,这是上位机的系统配置模块。

Company.Application.Login,这是上位机的用户登录模块。

Company.Application.Initialize,这是上位机的硬件加载模块,当然一些软件方面的加载也可放其中。

Company.Application.Share,这是上位机的共享模块,此模块的作用非常重要,负责各个模块的数据通讯。

Company.Application.Menu,这是上位机的菜单模块,负责菜单生成或管理。

Company.Application.More,这个表示其它模块,根据上位机功能而定。

第三、核心层模块

Company.Core,这是上位机的核心模块,与主业务无关,提供一些基础帮助类,全局类等,比如Json文件的序列化与反序列化,对话框管理器、缓存管理、本地语言包管理、各种helper类型等。

Company.Logger,这是上位机的日志模块,可以采用NLog或Log4net等常用组件,此模块也与主业务无关,被其它所有模块所引用,负责打印程序错误信息或调试信息。

Company.UI,这是上位机关于UI的资源模块,如WPF的模板样式定义、程序所引用的图标、图像、字体库、语言包、转换器,用户控件等。

第四、硬件层模块

Company.Hardware.Camera,这是上位机的工业相机抽象类模块,负责定义一台相机的功能,定义相机的配置参数和操作业务流程(如打开相机、使用相机、关闭相机)。

Company.Hardware.Camera.HIK,表示一台海康工业相机,它继承了相机抽象类,并实现其自身的API调用。

Company.Hardware.Camera.Other,表示其它工业相机,other要换成具体的相机名称,说明可能无限扩展其它厂家或其它型号的相机。

Company.Hardware.ControlCard,这是上位机的控制卡抽象基类,负责定义一张控制卡的功能,但不实现具体的操作流程,只规定操作接口,具体操作由子类实现。

Company.Hardware.ControlCard.DMC2610,比如雷赛运动控制卡DMC2610。

Company.Hardware.ControlCard.ADTech632XE,比如众为兴运动控制卡632XE。

其它的硬件都可以采用上述的命名方式去扩展。

第五、数据库模块

Company.Database.Core,这个模块定义了数据库的操作接口,仓储层的抽象类型 等。

Company.Database.EF,这是采用EF框架去对数据库进行增删改查的模块,其中的类型都继承于Core中的抽象类。

接下来,用一张结构图,演示详细的上位机架构
在这里插入图片描述
上位机开发架构设计高清大图链接地址 :

上位机课程思维导图

https://www.processon.com/view/link/64a10419111c1d7d8a19db04

重庆教主的VIP课程

WPF中关于Prism框架的学习课程

https://edu.51cto.com/course/33880.html

C#+WPF上位机开发课程(模块化与反应式编程)

https://edu.51cto.com/course/34143.html

C#+WPF项目实战MVVM模式开发《超市管理系统》

https://edu.51cto.com/course/33794.html

作者:重庆教主

相关文章:

C#+WPF上位机开发(模块化+反应式)

在上位机开发领域中,C#与C两种语言是应用最多的两种开发语言,在C语言中,与之搭配的前端框架通常以QT最为常用,而C#语言中,与之搭配的前端框架是Winform和WPF两种框架。今天我们主要讨论一下C#和WPF这一对组合在上位机开…...

【LeetCode 算法】Card Flipping Game 翻转卡片游戏-阅读题

文章目录 Card Flipping Game 翻转卡片游戏问题描述:EN 分析代码 Tag Card Flipping Game 翻转卡片游戏 问题描述: 在桌子上有 N 张卡片,每张卡片的正面和背面都写着一个正数(正面与背面上的数有可能不一样)。 我们…...

【leetcode】138.复制带随机指针的链表

方法一:暴力求解 1️⃣遍历原链表,复制节点尾插 2️⃣更新random,原链表中的random对应第几个节点则复制链表中的random就对应第几个 📖Note 不能通过节点中的val判断random的指向,因为链表中可能存在两个val相等的节点…...

svn工具使用

svn 介绍 解决之道: SCM:软件配置管理 所谓的软件配置管理实际就是对软件源代码进行控制与管理 CVS:元老级产品 VSS:入门级产品 ClearCase:IBM 公司提供技术支持 SVN:主流产品 什么是SVN&#xff…...

SpringBoot项目使用MyBatisX+Apifox IDEA 插件快速开发

今天跟大家介绍两个快速开发项目的插件。能大大提高开发效率。希望能帮助到大家。 1、MyBatisX 插件 MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率。但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题&#xf…...

Redis数据结构

Redis 支持的数据结构的列表 1、String:字符串,是 Redis 最基本的数据类型,可以存储字符串、整数和浮点数。 2、Hash:哈希表,由多个键值对组成,可以储存多个字段和值。 3、List:列表&#xff0c…...

解密Redis:应对面试中的缓存相关问题

文章目录 1. 缓存穿透问题及解决方案2. 缓存击穿问题及解决方案3. 缓存雪崩问题及解决方案4. Redis的数据持久化5. Redis的过期删除策略和数据淘汰策略6. Redis分布式锁和主从同步7. Redis集群方案8. Redis的数据一致性保障和高可用性方案 导语: 在面试过程中&#…...

读取application-dev.properties的中文乱码【bug】

读取application-dev.properties的中文编码【bug】 2023-7-30 22:37:46 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://blog.csdn.net/qq_51625007 禁止其他平台发布时删除以上此话 bug 读取application-dev.propert…...

Linux(centos7)如何实现配置iscsi存储多路径 及DM-Multipath的配置文件概述

安装多路径软件(系统默认安装) #第一:安装多路径软件yum -y install device-mapper device-mapper-multipath#第二:在CentOS7中启用多路径模块,mpathconf命令及相关模块加载(可以使用mpathconf -h查看用法&…...

DK7 vs JDK8 vs JDK11特性和功能的对比

JDK7 vs JDK8 vs JDK11特性和功能的对比 Java Development Kit (JDK) 是 Java 程序员所使用的开发工具包,它提供了编译、调试和运行 Java 程序所需的一切。JDK 在不同的版本中引入了许多新的特性和功能,下面我们来比较 JDK7、JDK8 和 JDK11 之间的一些重…...

你觉得企业为什么需要数据分析?

数据对于企业的作用就好比,一位士兵作战需要手枪一样,仅仅只是作为一项工具,帮助我们提高取得胜利的几率或者概率。数据只是数据,不代表业务,所起的作用也是有限的,网上那些夸大数据作用的,没有…...

SVN学习

SVN学习 以下总结是看了一个b站up主的视频总结出来的。 1. 简介 SVN是代码版本管理工具,它能记住每次的修改、查看所有修改记录、恢复到任何历史版本和恢复已经删除的文件。 SVN比起Git的好处就是使用简单,上手快;具备目录级权限控制&…...

vim怎么使用,vim使用教程,vimtutor怎么切换中文 汉化

vim 使用 在安装了 vim 的 unix 系统下可以使用 vimtutor zh_cn 开启下面的教程 序言 欢 迎 阅 读 《 V I M 教 程 》 —— 版本 1.7 Vim 是一个具有很多命令的功能非常强大的编辑器。限于篇幅,在本教程当中就不详细介绍了。本教程的…...

[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联

上一节讲解了后台Rbac微服务角色增删改查微服务,这里讲解权限管理Rbac微服务管理员的增删改查微服务以及管理员和角色关联微服务功能 一.实现后台权限管理Rbac之管理员增删改查微服务服务端功能 1.创建Manager模型 要实现管理员的增删改查,就需要创建对应的模型,故在server/r…...

2023-07-31力扣每日一题

链接: 143. 重排链表 题意: 将链表L0 → L1 → … → Ln - 1 → Ln变成L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 解: 线性表法还是好写的 这边搞一下翻转法,快慢指针求翻转点(翻转后面一半然后双指针合并…...

接口自动化报告,生成本地服务并自动打开时失败

错误原因: 端口号被占用 首先可以在cmd中调出命令窗口然后执行命令netstat -ano就可以查看所有活动的链接,找到被占用的端口号 1、通过命令taskkill /f /t /im "进程名称" ,根据进程的名称杀掉所有的进程。或者taskkill /f /t /p…...

Git 的基本概念和使用方式

Git 是一种分布式版本控制系统,它能够记录文件内容的变化,并且允许用户在这些变化之间轻松地进行切换。 Git 的基本概念如下: 1. 仓库(Repository):Git 存放项目代码的地方。通常,一个仓库对应一…...

【JVM】(三) 深入理解JVM垃圾回收机制(GC)

文章目录 前言一、死亡对象的判断方法1.1 引用计数算法1.2 可达性分析算法 二、垃圾回收算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法2.5 分代算法2.6 Minor GC 和 Major GC 前言 JVM 的垃圾回收机制(Garbage Collection)是 Java 中的重要特性之…...

Flink CEP(二) 运行源码解析

通过DemoApp学习一下&#xff0c;CEP的源码执行逻辑。为下一篇实现CEP动态Pattern奠定理论基础。 1. Pattern的定义 Pattern<Tuple3<String, Long, String>,?> pattern Pattern.<Tuple3<String, Long, String>>begin("begin").where(new…...

剑指Offer-学习计划(四)双指针(下)

剑指 Offer 57. 和为s的两个数字 剑指 Offer 58 - I. 翻转单词顺序 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 题目一&#xff1a;调整数组顺序使奇数位于偶数前面 输入一个整数数组&#xff0c;实现一个函数来调整该数组中数字的顺序&#xff0c;使得所有奇数在数组的…...

深度学习——常见注意力机制

1.SENet SENet属于通道注意力机制。2017年提出&#xff0c;是imageNet最后的冠军 SENet采用的方法是对于特征层赋予权值。 重点在于如何赋权 1.将输入信息的所有通道平均池化。 2.平均池化后进行两次全连接&#xff0c;第一次全连接链接的神经元较少&#xff0c;第二次全连…...

Python 进阶(七):高级文件操作(shutil 模块)

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 1. 简介2. 常用函数2.1 复制文件2.2 复制目录2.3 移动文件或目录2.4 删除文件或目录2.…...

保留网络:大型语言模型的Transformer继任者

原文信息 原文题目&#xff1a;《Retentive Network: A Successor to Transformer for Large Language Models》 原文引用&#xff1a;Sun Y, Dong L, Huang S, et al. Retentive Network: A Successor to Transformer for Large Language Models[J]. arXiv preprint arXiv:2…...

算法通关村第二关——反转链表青铜笔记

LeetCode 206.反转链表 建立虚拟结点辅助翻转 public ListNode reverseList(ListNode head) {ListNode ans new ListNode(-1);ListNode cur head;while(cur!null){ListNode curNext cur.next;cur.next ans.next;ans.next cur;cur curNext;}return ans.next; }不带虚拟头…...

【Linux】——线程安全

目录 关于线程进程的问题 可重入与线程安全 常见的线程安全的情况 常见的不可重入的情况 常见的可重入的情况 可重入与线程安全区别 可重入与线程安全联系 Linux线程互斥 进程线程间的互斥相关概念 互斥量mutex 互斥量mutex常用接口 互斥量改造抢票系统 互斥量的原…...

[React]生命周期

前言 学习React&#xff0c;生命周期很重要&#xff0c;我们了解完生命周期的各个组件&#xff0c;对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1、getDefaultProps() 设置默认的props&#xff0c;也可以用duf…...

【2023】Redis实现消息队列的方式汇总以及代码实现

Redis实现消息队列的方式汇总以及代码实现 前言开始前准备1、添加依赖2、添加配置的Bean 具体实现一、从最简单的开始&#xff1a;List 队列代码实现 二、发布订阅模式&#xff1a;Pub/Sub1、使用RedisMessageListenerContainer实现订阅2、还可以使用redisTemplate实现订阅 三、…...

ARM裸机-10

1、X210开发板和光盘资料 1.1、配置信息 CPU&#xff1a;三星S5PV210 内存&#xff1a;512M DDR2 SDRAM Flash&#xff1a;4GB iBand LCD&#xff1a;7寸&#xff0c;分辨率800x480 触摸屏&#xff1a;电容触摸屏 2、X210开发板硬件手册 3、X210开发板刷系统 3.1、什么是刷…...

「C/C++」C/C++指针详解

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「算法」数据结构与算法「File」数据文件格式 目录 一、术语…...

提高电脑寿命的维护技巧与方法分享

在维护电脑运行方面&#xff0c;我有一些自己觉得非常有用的技巧和方法。下面我将分享一些我常用的维护技巧&#xff0c;并解释为什么我会选择这样做以及这样做的好处。 首先&#xff0c;我经常清理我的电脑内部的灰尘。电脑内部的灰尘会影响散热效果&#xff0c;导致电脑发热…...