今日继续我的C#winform上位机学习之路
这系列笔记的目标是尝试编写一个能够与西门子PLC进行以太网口通信的上位机软件。
文章提供完整代码解释、设计点解释、测试效果图、完整工程下载
本章主要学习:Winform多个窗体的一些操作 、无边框窗体的创建、Combox组件插入枚举类型、日志委托的添加使用、
只是个人学习方面的笔记,如有疏漏实乃正常......
目录
Winform 西门子PLC通信窗口的控件摆放与声明:
Winform 添加新的窗口:
Winform多窗口设置窗口加载顺序:
Winform去除窗口边框:
按键操作TabControl调出新窗口:
按键清除Tabcontrol中的窗体内容:
枚举类型与Combox控件的绑定:
日志的添加建立_绑定imagelist:
日志的添加建立_imaginelist添加成员:
listview编辑列属性(日志时间内容):
日志的添加使用:
winform常用图标库下载:
网上资料查阅网址贴出:
Winform 西门子PLC通信窗口的控件摆放与声明:
Form1()窗体设计控件如下:
ComboBox:CPU类型、变量类型
Button:连接PLC、读取、写入
Textbox:IP地址、变量地址、读取长度、写入数值
RichTextBox:读写信息
Winform 添加新的窗口:
先右键项目添加窗体:
然后可以进行改名称,并进行添加:
新窗体控件摆放:
tabControl和 button
前者用于确定框区大小,后者用于交互调出另一个表单
可以在属性中查看框区大小,为设计做出便利:
Winform多窗口设置窗口加载顺序:
现在我们项目中有了俩个窗口,但明显我们希望新创建的串口MainForm是第一个运行的,然后在Mainform的按键操作下再调出form1,那如何设置好Mainform先加载呢:
我们只需进入Program.cs中,将原本的Form1()改为MainForm()即可 :
启动后发现确实变成MainForm的界面了:
Winform去除窗口边框:
在实现接下来的设计之前,我们需要对form1进行一些改进,主要是外观上的改进:
然后去除其边框:
最后别忘了改进其大小,使其适合于之前的tabControl属性中的大小:
按键操作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中
这样就可以实现按下“西门子”按键,就调出之前的Form1()窗体贴在tabcontrol里了:
按键清除Tabcontrol中的窗体内容:
这里我也是进行学习提升一下,
将按键的操作改进为:第二次按下“西门子”就清除Tabcontrol中的内容:
别忘了定义Bool型变量帮助按键的操作形成一个循环:
bool button1_cg = false;
private void button1_Click(object sender, EventArgs e)
{
//第一次点击会将 Form1()添加进Tabcontrol中
if (button1_cg==false)
{
button1_cg = true;
Add_TabPage("西门子", new Form1());
}
//第二次就会清除所有标签页
else if(button1_cg==true)
{
button1_cg = false;
// 假设你的TabControl的名字是tabControl1
// 清除所有的标签页
while (tabControl1.TabPages.Count > 0)
{
tabControl1.TabPages.RemoveAt(0);
}
}
}
再次按下清空效果:
枚举类型与Combox控件的绑定:
在上篇文章我们提到了与西门子通信的库xktcomm中,CPU类型是一个枚举类型(enum):
而我们希望其枚举的类型合理地进入到我们的Form1()窗体的Combox组件中去枚举:
代码实现:
//表单初始化的类
public Form1()
{
InitializeComponent();
this.Load += Form1_Load1;
}
private void Form1_Load1(object sender, EventArgs e)
{
//加载cmb_CPUType组件的DataSource属性
//加载名称源GetNames是Enum数据类型的xktComm.Common.CPU_Type
this.cmb_CPUType.DataSource = Enum.GetNames(typeof(xktComm.Common.CPU_Type));
}
绑定后初始化效果展示:
用同样方式进行变量类型的枚举绑定:
代码如下:
//表单初始化的类
public Form1()
{
InitializeComponent();
this.Load += Form1_Load1;
}
private void Form1_Load1(object sender, EventArgs e)
{
this.cmb_CPUType.DataSource = Enum.GetNames(typeof(xktComm.Common.CPU_Type));
this.cmb_VarType.DataSource = Enum.GetNames(typeof(xktComm.Common.VarType));
}
效果如下:
日志的添加建立_绑定imagelist:
回到设计界面,点击组件右上角弹出listview:
添加新组件imagelist并绑定:
日志的添加建立_imaginelist添加icon成员:
第一次点击imaginelist右上角的三角调出图像集合编辑时,是没有图像成员的,这里就需要添加了
文章末尾提供winform常用图标库下载地址,这里我也是搜索到了需要的三个图标,并放在了桌面
添加成功:
但我们发现有位成员是白色的,没有图标,这时点属性知道它大小为64*64,而imaginelist设定的图标大小为16*16,这里改进一下就行了:
但计时这样我还是发现没解决问题,最终我将一堆。ico文件导入看哪些正常、哪些不支持:
然后选择差不多元素的,按箭头移位到位置替换了:
如果有大神知道如何将ico文件正确修改导入,希望能在评论区告知学习~~~~~~
最后提一嘴,别忘了将刚才的imaginelist的图像属性的64,64改回16,16,不然日志图标icon显示会变得超级大:
listview编辑列属性(日志时间内容):
接下来继续对 组件属性进行修改:
点击编辑列
就会看到日志的时间与内容:
日志的添加使用:
日志的使用需要创建委托:
//info 表示报警级别 ,log 表示报警信息
public delegate void AddLog(int info, string log);
添加AddLog的实际方法:
/*
首先判断是否需要通过Invoke调用该方法。如果不需要,则直接执行下面的代码。
创建一个ListViewItem对象lst,用于存储日志信息。
使用DateTime.Now.ToString(“yyyy/MM/dd HH:mm:ss”)获取当前时间,并将其添加到lst中。
将Log参数添加到lst的子项中。
将lst插入到lstInfo控件的第一个位置。
如果需要通过Invoke调用该方法,则使用Action委托和Invoke方法来执行相同的操作。
*/
//写入日志委托方法
private void AddLog(int info, string Log)
{
if (!lstInfo.InvokeRequired)
{
//创建ListViewItem ,将时间与info放进去
ListViewItem lst = new ListViewItem(" " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), info);
lst.SubItems.Add(Log);
lstInfo.Items.Insert(0, lst);
}
else
{
Invoke(new Action(() =>
{
ListViewItem lst = new ListViewItem(" " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), info);
lst.SubItems.Add(Log);
lstInfo.Items.Insert(0, lst);
}));
}
}
初始化作绑定:
myaddlog=this.AddLog;//绑定方法
在连接PLC按键函数处调用一下这个方法:
//连接/断开PLC
private void btn_Connect_Click(object sender, EventArgs e)
{
//连接PLC
if (button1_Clickf == true)
{
btn_Connect.Text = "断开PLC";
btn_Connect.BackColor = Color.Red;
button1_Clickf = false;
myaddlog(isconnected ? 1 : 0, isconnected ? "PLC连接成功" : "连接PLC失败");
}
//断开PLC
else if (button1_Clickf == false)
{
btn_Connect.Text = "连接PLC";
btn_Connect.BackColor = SystemColors.ActiveCaption;
button1_Clickf = true;
}
}
myaddlog(isconnected ? 0 : 1, isconnected ? "PLC连接成功" : "连接PLC失败");
中1和0表示的对应引用哪个图标:
效果展示:
winform常用图标库下载:
https://download.csdn.net/download/qq_64257614/89109129
网上资料查阅网址贴出:
【Winform学习笔记(七)】Winform无边框窗体拖动功能_winform窗体拖动-CSDN博客
2020-12-07_窗体控件imagelist添加图片-CSDN博客