C#学习笔记15:上位机助手_usercontrol窗体内嵌的应用

今日完善一下之前的上位机助手,做一个组合窗体内嵌的多功能助手软件应用,

与之前的上位机软件相比:

更注重控件能够随着窗体缩放而缩放变换,串口助手部分能自动后台检测串口设备,解决市面上大部分串口助手的打开初始化会卡顿的问题 ( 多线程后台刷新技术 )

本文不会一步一步讲实现,只粗略解释一些控件的摆放等 ,且到目前为止我这个多功能助手开发还未完整,因此本文将提供下载的将是功能不太完整的上位机助手.....

 文章提供完整代码解释、设计点解释、测试效果图、完整工程下载

目录

C# Winform 上位机部分:

主要控件如下:

自动排列组件TableLayoutPanel与Group组件:

窗体内嵌窗体:

新建一个额外的无边框窗体:

 Winform去除窗口边框:

按键操作TabControl调出新窗口:

按键清除Tabcontrol的窗体内容:

usercontrol窗体内嵌应用:

AddControl函数的修改:

与按键的配合调用:

效果如下:

按键调出新窗口:

测试效果展示:

目前测试工程下载:


C# Winform 上位机部分:

 主要完成了串口助手以及SYN6288助手,有关串口数据绘图的部分还在开发实验......

主要控件如下:

自动排列部件(TableLayoutPanel)、区域分组组件(Groupbox)、按键(Button)、Tabcontrol、checkbox等......

自动排列组件TableLayoutPanel与Group组件:

 TableLayoutPanel与Group组件一般都是同时使用,将TableLayoutPanel 放置于窗体中,并设置其dock属性为fill,即可自动排列放置在其中的控件进行适应窗口大小的变换

但TableLayoutPanel 一个分区只能放置一个控件,因此它要配合Group组件使用,Group组件支持方式多个控件在其内部

自动排列部件(TableLayoutPanel)可以使组件适应窗口大小:

首先别忘记调整它的Dock属性以使其适应填满窗口大小:

可以右键空白处或者点击右上角的三角 编辑添加行与列:

TableLayoutPanel只允许一个区域只存在一个组件,这就需要另一个组件(Groupbox)让其能够在一个区域存在多个组件:

我们一般不需要这个组件在上方显示名字,所以只需要将其text属性删掉,并设置其Dock属性为fill就行:

窗体内嵌窗体:

这个设计不推荐,比较麻烦,是我在过程中选择的一条不怎么好的解决道路,因为这样生成的内嵌窗体没法适应主窗口大小,建议直接跳转到下文usercontrol

新建一个额外的无边框窗体:

有的时候我们想要在窗体中开其余窗体应用,所以需要新建一个额外无边框窗体内嵌在原先的Main_Form(我第一个窗体名为Main_Form)中

下文以创建嵌入一个serial_form为例:

首先嵌入一个Tabcontrol在合适的位置,并设置其Dock为fill,并点右上角的三角删掉所有的TabPage,只留最基础的一个:然后查看其size属性(用于确定新内嵌serial_form大小):

 然后在解决方案资源管理器右键添加窗体并右键改名:

 

 进入Program.cs中,设定确保Main_Form是我们第一个加载的主要窗体:

 Winform去除窗口边框:

接下来去除serial_form 的边框,并设定大小:

按键操作TabControl调出新窗口:

现将以下俩个方法写入MainForm中,位置已经截图

(截图中函数只保留名字,具体实现被折叠了)

        //添加窗体实例进Tabpage中public void Add_TabPage(string str, Form myForm) //将标题添加进tabpage中{if (!this.tabControlCheckHave(this.tabControl1, str)){this.tabControl1.TabPages.Add(str);this.tabControl1.SelectTab((int)(this.tabControl1.TabPages.Count - 1));myForm.FormBorderStyle = FormBorderStyle.None;myForm.TopLevel = false;myForm.Show();myForm.Parent = this.tabControl1.SelectedTab;}}public bool tabControlCheckHave(TabControl tab, string tabName) //看tabpage中是否已有窗体{for (int i = 0; i < tab.TabCount; i++){if (tab.TabPages[i].Text == tabName){tab.SelectedIndex = i;return true;}}return false;}

然后在合适的按键选项中 调用第一个函数的方法:

public void Add_TabPage(string str, Form myForm) //将标题添加进tabpage中

 这样就可以实现按下按键,就调出之前的Serial_form()窗体贴在tabcontrol里了:

按键清除Tabcontrol的窗体内容:

这里我也是进行学习提升一下,

将按键的操作改进为:第二次按下“串口助手”就清除Tabcontrol中的内容:

别忘了定义Bool型变量帮助按键的操作形成一个循环:

 bool Serial_button1_cg = false; 
//第一次调出串口助手窗体,第二次按下“串口助手”就清除Tabcontrol中的内容://选择串口助手工具://第一次调出串口助手窗体,第二次按下“串口助手”就清除Tabcontrol中的内容:private void Serial_Click(object sender, EventArgs e){if(Serial_button1_cg == false){Add_TabPage("串口助手", new Serial_form());Serial_button1_cg = true;}//第二次就会清除所有标签页else if (Serial_button1_cg == true){// 清除所有的标签页while (tabControl1.TabPages.Count > 0){tabControl1.TabPages.RemoveAt(0);}Serial_button1_cg = false;}}

usercontrol窗体内嵌应用:

上文介绍的form'窗体内嵌含有各种不好的设计缺陷,不推荐,这里直接推荐usercontro窗体内嵌

添加用户控件窗体并改名:(后续就和普通form一样设计了......)

在这之后,我这里的Usercontrol预先设计编程为了串口助手

AddControl函数的修改:

在 Windows Forms 应用程序中,FormUserControl 是两种不同的控件类型,它们不能直接互换使用。Form 是一个窗口,它可以包含其他控件,并可以独立显示;而 UserControl 是一个可以包含其他控件的复合控件,但它通常需要被放置在 Form 或其他容器控件中。

public void Add_TabPage(string str, Control myControl) // 将 Control 替换为 Form  
{  if (!this.tabControlCheckHave(this.tabControl1, str))  {  TabPage newTabPage = new TabPage(str);  this.tabControl1.TabPages.Add(newTabPage);  this.tabControl1.SelectTab(this.tabControl1.TabPages.Count - 1);  myControl.Dock = DockStyle.Fill; // 确保控件填充整个TabPage  newTabPage.Controls.Add(myControl); // 将控件添加到TabPage中  }  
}  public bool tabControlCheckHave(TabControl tab, string tabName)  
{  for (int i = 0; i < tab.TabCount; i++)  {  if (tab.TabPages[i].Text == tabName)  {  tab.SelectedIndex = i;  return true;  }  }  return false;  
}

与按键的配合调用:

与bool类型变量配合,第二次按下“串口助手”就清除Tabcontrol中的内容:

bool Serial_button1_cg = false; 
//第一次调出串口助手窗体,第二次按下“串口助手”就清除Tabcontrol中的内容: //选择串口助手工具://第一次调出串口助手窗体,第二次按下“串口助手”就清除Tabcontrol中的内容:private void Serial_Click(object sender, EventArgs e){if(Serial_button1_cg == false){Add_TabPage("串口助手", new Serial_form1());Serial_button1_cg = true;}//第二次就会清除所有标签页else if (Serial_button1_cg == true){// 清除所有的标签页while (tabControl1.TabPages.Count > 0){tabControl1.TabPages.RemoveAt(0);}Serial_button1_cg = false;}}

效果如下:

按下按键,可以调出usercontrol在Tabcontrol中:

按键调出新窗口:

这是我之前写好的窗口,我在原工程新建了一个窗体,并将其全部方法复制过来了:

现在我在Main_form放置了一个SYN6288的Button控件,希望按下这个button就打开这个新窗口SYN6288_serial() ,那这个按键的事件方法就可以这么写:

        //SYN6288 语音模块串口助手private void SYN6288_serial_Click(object sender, EventArgs e){// 实例化新窗口  SYN6288_serial secondForm = new SYN6288_serial();secondForm.ShowDialog();}

这个有俩种不同的方法可以选择,适合不同应用场景:

    // 显示新窗口  // 使用Show方法,允许用户与两个窗口同时交互  // secondForm.Show();  // 或者使用ShowDialog方法,新窗口关闭后才会返回继续执行主窗口的代码  // secondForm.ShowDialog();  

测试效果展示:

虽然可以开启虚拟串口测试,但我更喜欢真实串口收发的效果(虚拟串口模拟不了丢包等真实情况,虽然串口上位机不需要处理这个情况),因此我使用俩个zigbee模块进行真实的串口收发测试!

自动检测端口:

正常接收GB2312中文编码:

接收转为HEX:

显示接收时间:

 正常发送GB2312中文编码:

调出SYN6288语音助手:

SYN6288语音助手部分的功能就不单独做解释了,这篇文章有:

C#学习笔记14:SYN6288语音模块_Winform上位机控制软件-CSDN博客

 

目前测试工程下载:

本文只粗略解释一些控件的摆放等 ,到目前为止我这个多功能助手开发还未完整,因此本文将提供下载的将是功能不太完整的上位机助手.....

https://download.csdn.net/download/qq_64257614/89628954

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/397979.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux服务管理-Nginx配置

静态解析主要解析html、css动态解析需要解析php 动态资源通过轮询分配到后端的Apache服务器处理 apache是同步阻塞&#xff0c;nginx是异步非阻塞

论文阅读笔记:Efficient Teacher: Semi-Supervised Object Detection for YOLOv5

Efficient Teacher: Semi-Supervised Object Detection for YOLOv5 1 背景1.1 动机1.2 问题 2 创新点3 方法4 模块4.1 伪标签分配4.2 Epoch Adapter 5 效果5.1 与SOTA方法对比5.2 消融实验 论文&#xff1a;https://arxiv.org/pdf/2302.07577v3.pdf 代码&#xff1a;https://g…

Python 常用内置函数

目录 1、enumerate函数 1.1、for循环中使用 1.2、enumerate指定索引的起始值 1.3、enumerate在线程中的作用 2、Map 函数 2.1、map()函数可以传多个迭代器对象 3、lambda表达式&#xff08;匿名函数&#xff09; 示例 4、sort函数和sorted函数 4.1、sort()函数 4.2、…

map和set的使用

关联式容器 在学习关联式容器之前&#xff0c;我们学习过的容器有vector、list、deque…这些容器称为序列式容器&#xff0c;单纯的存储数据存储的数据没有关联性。 即将学习的map 和set属于关联式容器&#xff0c;其里面存储的是<key, value>结构的键值对&#xff0c;…

制造知识普及(九)--企业内部物料编码(IPN)与制造商物料编码(MPN)

在日常的物料管理业务逻辑中&#xff0c;一物一码是物料管理的基本的业务规则&#xff0c;不管物料从产品开发还是仓库管理&#xff0c;甚至成本核算&#xff0c;都要遵循这个原则&#xff0c;才能保证产品数据的准确性&#xff0c;才具备唯一追溯的可行性。大部分企业都是这种…

某通电子文档安全管理系统 CDGAuthoriseTempletService1接口SQL注入漏洞复现 [附POC]

文章目录 某通电子文档安全管理系统 CDGAuthoriseTempletService1接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现0x06 修复建议某通电子文档安全管理系统 CDGAuthoriseTempletService1接口SQL注入漏…

C#数据类型转换

代码&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace Test05 {class Program{static void Main(string[] args){double db 2008;//声明一个double类型变量db&#xff0c;并初始化为2008object obj db;//对db…

JAVA实现判断小程序用户是否关注公众号

本文主要描述了判断小程序用户是否关注公众号的逻辑实现及部分代码 首先阐述一下大致流程&#xff1a; 1、在将小程序和公众号绑定至同一个微信开发平台下&#xff1b; 2、后端拉取公众号已关注用户列表&#xff0c;并获取其中每一个用户的unionID&#xff0c; 建立已关注用户…

OCR调研

OCR调研 一、介绍 OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;是一种将图像中的文字转换为计算机可处理格式的技术。OCR技术经历了从传统OCR到基于深度学习的OCR的转变。深度学习OCR技术通过模拟人脑神经元结构处理文本和图像数据&am…

MATLAB - 强化学习(Reinforcement Learning)

系列文章目录 前言 一、什么是强化学习&#xff1f; 强化学习是一种以目标为导向的计算方法&#xff0c;计算机通过与未知的动态环境交互来学习执行任务。这种学习方法能让计算机在没有人工干预和明确编程的情况下&#xff0c;做出一系列决策&#xff0c;使任务的累积奖励最大化…

cmake 编译教程

参考链接&#xff1a;cmake使用详细教程&#xff08;日常使用这一篇就足够了&#xff09;_cmake教程-CSDN博客 一、只有一个源文件的程序编译 首先在当前目录下创建两个文件 hello.cpp CMakeLists.txt &#xff08;注意CMakeLists大小写&#xff0c;不要写错了&#xff09; …

推荐一个优秀的 .NET MAUI 组件库

目录 前言 组件介绍 组件展示 布局 按钮 复选框 进度条 导航栏 组件地址 最后 前言 .NET MAUI 的发布&#xff0c;项目中可以使用这个新的跨平台 UI 框架来轻松搭建的移动和桌面应用。 为了帮助大家更快地构建美观且功能丰富的应用&#xff0c;本文将推荐一款优秀…

AcCode核心思路

文章目录 在线OJ项目核心思路1. 项目介绍2.预备知识理解多进程编程为啥采用多进程而不使用多线程?标准输入&标准输出&标准错误 3.项目实现题目API实现相关实体类定义新增/修改题目获取题目列表 编译运行编译运行流程 4.统一功能处理 在线OJ项目核心思路 1. 项目介绍 …

有序转化数组(LeetCode)

题目 给你一个已经 排好序 的整数数组 和整数 、 、 。对于数组中的每一个元素 &#xff0c;计算函数值 &#xff0c;请 按升序返回数组 。 解题 在时间复杂度为解决问题 def sortTransformedArray(nums, a, b, c):def f(x):return a * x * x b * x cn len(nums)result…

4个从阿里毕业的P7打工人,当起了包子铺的老板

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247483727&idx1&sndb05d8c1115a4539716eddd9fde4e5c9&chksmc0e47813f793f105017fb8551c9b996dc7782987e19efb166ab665f44ca6d900210e6c4c0281&scene21#wechat_redirect 《网安面试指南》h…

学生公寓电费信息管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公寓管理员管理&#xff0c;学生管理&#xff0c;楼层信息管理&#xff0c;用电情况管理&#xff0c;缴费清单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;用电情况…

【数据结构】六、图:4.图的遍历(深度优先算法DFS、广度优先算法BFS)

三、基本操作 文章目录 三、基本操作1.图的遍历1.1 深度优先遍历DFS1.1.1 DFS算法1.1.2 DFS算法的性能分析1.1.3 深度优先的生成树和生成森林 1.2 广度优先遍历BFS1.2.1 BFS算法1.2.2 BFS算法性能分析1.2.3 广度优先的生成树和生成森林 1.3 图的遍历与图的连通性 1.图的遍历 图…

Nginx系列-Nginx Location匹配规则

文章目录 Nginx系列-Nginx Location匹配规则1. 语法基础2. 匹配规则2.1 精确匹配&#xff08;&#xff09;2.2. 最长前缀匹配&#xff08;^~&#xff09;2.3. 正则表达式匹配&#xff08;~和~*&#xff09;2.4. 普通前缀匹配&#xff08;无修饰符&#xff09;2.5. 默认匹配&…

贷齐乐hpp+php特性注入

文章目录 运行过程waf第一层waf拦截第二层waf拦截 数据库查询语句注入思路注入 运行过程 foreach ($_REQUEST as $key > $value) {$_REQUEST[$key] dowith_sql($value);}$request_uri explode("?", $_SERVER[REQUEST_URI]);if (isset($request_uri[1])) {$rewr…

OpenGL3.3_C++_Windows(34)

demo 1 Fresnel-Schlick PBR直接光源 顾名思义&#xff1a;直接光源指有光源直接照射到点p 的辐射强度&#xff0c;由于一个光源只会有一个光线wi影响点p&#xff0c;所以和之前的计算没什么差异对于影响p的光源&#xff0c;并不需要积分计算半球形辐照度&#xff0c;遍历每个…