一个实际的上位机项目,不大可能只有一个窗体。通常我们会有启动画面、工艺画面、参数画面、报警画面等等。那我们如何在C#中实现这些窗体切换呢?本节案例课程中,我们将带领大家实现一个具有启动画面、仪表画面和参数设置画面的迷你型上位机项目。这个迷你项目的画面结构是这样的。
图1 上位机案例它的网络结构比较简单,就是一台工控机连接一台PLC。如下图所示。
图2 网络图整个上位机画面分为两个区域。下方是功能导航区,我们可以通过这些按钮切换画面。画面有三个,分别是启动画面、仪表画面和设置画面。
01
画面结构
新建一个项目,命名为MicroSCADA。
图3 新建项目然后把自带的窗体Form1重命名为Main。
图4 重命名窗体窗体Main属性修改如下:
打开新建的Main窗体,从左侧工具箱中拖一个TableLayoutPanel控件到窗体上。
图5 添加TableLayoutPanel控件设置控件TableLayoutPanel的Dock属性为Fill。
图6 设置Dock这里补充说一下,所有的可视化控件都有Dock属性。它用于设置控件在容器中的停靠方式。我们可以根据布局需要选择它的停靠方式。
图7 Dock属性再点击窗体Main上TableLayoutPanel控件右上角的黑色三角。
图8 移除多余的列然后点击“移除最后一列“。
图9 只剩上下两行的TableLayoutPanel这样布局控件TableLayoutPanel只剩下了上下两行。我们分别为上下两行从左侧工具箱拖一个Panel控件进去。
图10 添加Panel两个Panel控件的Dock属性都设置为Fill。再点击控件TableLayoutPanel右上角的黑色三角按钮,选择“编辑行和列”。将下面的行设置为“绝对-56像素”。上面的行设置为“百分比-100%”。
图11 设置行列样式再选中控件TableLayoutPanel,设置它的属性“CellBorderStyle“为Singal。
图12 属性CellBorderStyle设置完成后的Main窗体这样的。
图13 设置完成的窗体从左侧工具箱拖3个按钮到控件TableLayoutPanel的下面行中。按钮的Dock属性都设置为Left。宽度统一设置为60,高度是自动限定的。
图14 添加按钮为每个按钮设置属性,参见下面列表。
完成后的效果如下:
图15 导航效果然后再添加三个窗体,用作子画面。三个窗体分别命名为FrmSetting、FrmHome和FrmMeter。
图16 子画面
02
启动画面
窗体Home作为启动画面,比较简单。拖一个Label控件到窗体上,属性设置如下即可。
完成后的效果如下图所示。
图17 启动画面接下来我们用按钮来打开FrmHome画面。画面切换的基本原理就是通过Panel来动态加载不同的画面实现的。为了实现Panel的动态加载,我们先创建一个自定义方法。//该自定义方法用于将窗体加载到Panel控件上//如果看不懂也没关系,知道原理就行,通过学习的深入,后面慢慢就会理解private static void OpenWindow(Form Frm, Panel panel_Show){ foreach (Control control in panel_Show.Controls) { if (control != null) { if(control is Form) { Form frm = (Form)control; frm.Close(); } } }
panel_Show.Controls.Clear(); Frm.TopLevel = false; Frm.FormBorderStyle = FormBorderStyle.None; Frm.Dock = DockStyle.Fill; Frm.Parent = panel_Show; Frm.Show();}然后双击按钮btnHome,输入下面代码。private void btnHome_Click(object sender, EventArgs e) { FrmHome frm = new FrmHome(); //调用自定义f方法,加载窗体 OpenWindow(frm, panel1); }为了使程序运行时默认打开Home页面。我们在窗体的加载事件中输入下面代码。private void Main_Load(object sender, EventArgs e) { //在窗体加载时触发按钮btnHome的点击事件,加载启动画面 btnHome.PerformClick(); }现在运行程序,我们就可以看到下图所示的效果了。
图18 启动画面调用
03
仪表画面
仪表画面直接照搬之前的例子即可。但是有一点需要注意,因为数据读取方法GetData在主画面Main里面。而仪表控件在子画面FrmMeter中,所以我们需要将GetData读取的数据放到一个全局变量中。然后子画面FrmMeter中的仪表控件关联这个全局变量。为项目添加一个类文件,命名为Data。
图19 添加类文件类文件Data的代码如下://该类用于定义全局变量,通过全局变量传递数据internal class Data{ public static double Data1 = 0; public static double Data2 = 0; }线程方法GetData中的代码也需要做相应修改。private void GetData(){ Sharp7.S7Client plc = new Sharp7.S7Client(); plc.Disconnect(); plc.ConnectTo("192.168.0.12", 0, 1); if (plc.Connected) { while (true) { Thread.Sleep(1000); byte[] data = new byte[1024]; plc.ReadArea(0x84, 1, 8, 8, 0x02, data); //读取的值传递给全局变量 Data.Data1= Sharp7.S7.GetRealAt(data, 0); Data.Data2 = Sharp7.S7.GetRealAt(data, 0); } }}为了美观,我们还可以用Label为两个仪表添加一些信息文本。然后双击按钮btnMeter,为其点击事件添加画面切换代码。private void btnMeter_Click(object sender, EventArgs e){ FrmMeter frm = new FrmMeter(); OpenWindow(frm, panel1);}运行程序,点击按钮btnMeter,我们就可以看到仪表画面了。
图20 仪表画面调用
04
设置画面
最后是设置画面。在设置画面里,我们可以设置目标PLC的IP地址。设置信息是需要保持的。不能在重启程序后就丢失了。为了保持设置数据,我们还需要为程序添加一个设置文件。
图21 添加设置文件然后打开添加的设置文件,添加信息如下。
图22 添加成员设置文件可以理解为PLC里面的保持寄存器。在上图中,我们创建了一个名为PLC的可保持变量。设置画面如下图所示。因为比较简单,不再赘述。
图23 设置画面在地址信息输入变化时,将值保存到设置文件中。private void txtPLC_TextChanged(object sender, EventArgs e){ Settings1.Default.PLC = txtPLC.Text; Settings1.Default.Save(); }然后在窗体加载时需要读取设置值到文本框中。private void FrmSetting_Load(object sender, EventArgs e){ txtPLC.Text = Settings1.Default.PLC;}最后回过头把线程方法GetData里面的IP地址替换为Settings1.Default.PLC。
图24 修改GetData
05
总结
到此一个具有启动画面、仪表画面和设置画面的迷你上位机项目就完成了。通过该上位机,我们可以读取指定IP的PLC里面的数据,并通过仪表直观地展示。HwLib(慧兰博)技术团队专注于高端自动化技术,如果您对我们的技术教程感兴趣的话,可以X宝上搜索店铺“hwlib”或者“慧兰博”
关于HwLib(慧兰博)技术团队的更多信息:www.hwlib.com.cn
HwLib(慧兰博)技术团队技术资料:
https://www.jianguoyun.com/p/DR20ZAEQq_K3CBivk5kD
或者
https://pan.baidu.com/s/1wXJYgFf-FIUVNbC7IHdxEg?pwd=1234
提取码:1234
END
往期导读
C#上位机开发入门(9)-异步
C#上位机开发入门(8)-轮询
C#上位机开发入门(7)-通信(下)
C#上位机开发入门(6)-通信(上)
C#上位机开发入门(5)
C#上位机开发入门(4)
C#上位机开发入门(3)
C#上位机开发入门(2)
C#上位机开发入门(1)
C#上位机6周快速入门连载预告
C#上位机开发的学习建议
C#通过S7Plus协议访问S7-1200/1500中的符号变量
上位机开发常用的UI库(WinForm)
C#开发的轻量级LiteDB数据库
MAUI开发(2)-添加新控件
MAUI开发(1)-创建MAUI应用
WinForm如何实现多语言界面
C#如何将bytes转换为浮点型
自动化系统和信息化系统的一点差异
专注于智能制造工程基础架构与实践
|