今日完善一下之前的上位机助手,做一个组合窗体内嵌的多功能助手软件应用,
与之前的上位机软件相比:
更注重控件能够随着窗体缩放而缩放变换,串口助手部分能自动后台检测串口设备,解决市面上大部分串口助手的打开初始化会卡顿的问题 ( 多线程后台刷新技术 )
本文不会一步一步讲实现,只粗略解释一些控件的摆放等 ,且到目前为止我这个多功能助手开发还未完整,因此本文将提供下载的将是功能不太完整的上位机助手.....
文章提供完整代码解释、设计点解释、测试效果图、完整工程下载
目录
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 应用程序中,
Form
和UserControl
是两种不同的控件类型,它们不能直接互换使用。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