打开vs2019
创建新项目》类库。NET Framework》命名LED,勾选放在同一目录》创建
在LED项目右键》添加,新建项》用户控件(Windows)》添加
在控件容器内,画出控件布局。
修改控件样式到如下图:按键FlatStyle=Flat;
到这里UI就差不多了。
就像买了年画,就可以往家里大门上贴了。
在解决方案》右键添加,新建项目》Windows窗体应用》下一步
在工具栏左上角就有我们自定义的控件:UserControl1双击他
这样我们就可以像按钮控件一样使用他了。
这里,我们就该开始改造这个模块了。
把控件名改为led,再 生成》重新生成解决方案
把led看成一个模块。重复加这个模块,可以想到什么呢?
如果单独写的话,源头改了代码,那后面都要改,代码地震是我们不想看到的。
led这样的套娃结构该怎么办?大家想一想对象的本质:字段/属性 方法。
那我们可以用一个属性,来确定是哪个对象,就和汽车的牌照一样。
控件默认有个Tag,这个和Text一样用。但这一个怎么够用呢!所以我们要自定义一些属性和方法出来。
在led控件下,添加代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LED
{
public partial class led : UserControl
{
public led()
{
InitializeComponent();
}
//==========字段(私有,每个对象都是独立的个体)
UInt32 ledNO = 0;//led灯编号
bool ledstart = false;//led灯状态
string ledAddress1 = "";//led灯 地址1
string ledAddress2 = "";
//==========属性(套娃模式,设置对象字段)可以脑补一下套娃场景
[Category("led灯编号")]
[Description("第几个led灯")]
public UInt32 LedNO
{
get { return ledNO; }
set { ledNO = value; }
}
[Category("led灯状态")]
[Description("开/关")]
public bool Ledstart
{
get
{
//plc读,指定位置数据
ledstart = true;//如得到1
return ledstart;
}
set
{
ledstart = value;//这样就可以套娃模式下通过设置参数来显示效果
if (ledstart)
{
label2.BackColor = Color.Blue;//开
//plc写,led开
}
else
{
label2.BackColor = Color.Red;//关
//plc写,led关
}
}
}
[Category("led灯地址")]
[Description("地址")]
public string LedAddress1
{
get { return ledAddress1; }
set { ledAddress1 = value; }
}
public string LedAddress2
{
get { return ledAddress2; }
set { ledAddress2 = value; }
}
//==========方法(按键是一个一个按的,可以理解成排队)
//比如食堂打饭,按键排好队,一个一个上。
//事件队列
[Category("led事件")]
[Description("事件加载")]
public event EventHandler openbtn;//打开事件
public event EventHandler closebtn;//关闭事件
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)//开
{
Ledstart = true;
}
private void button2_Click(object sender, EventArgs e)//关
{
Ledstart = false;
}
}
}
//到这里时,设置启动(不是自定义控件)
//这里我们按开和关就能控制右边label指示灯颜色了。
label是3个空白符,然后修改的背景色当指示灯用的。
利用属性,在set和get里加入我们需要的其他功能。这样的效果就是。设置一个bool属性时,1会把指示灯点亮,0会把指示灯熄灭
bool ledstart = false;//led灯状态
[Category("led灯状态")]
[Description("开/关")]
public bool Ledstart
{
get
{
//plc读,指定位置数据
ledstart = true;//如得到1
return ledstart;
}
set
{
ledstart = value;//这样就可以套娃模式下通过设置参数来显示效果
if (ledstart)
{
label2.BackColor = Color.Blue;//开
//plc写,led开
}
else
{
label2.BackColor = Color.Red;//关
//plc写,led关
}
}
}
//这里差不多是有个样子了,剩下的就是要好好修饰一下了。
LED灯没有编号,那我们就去控件里改编号。想一下思路:模板一直再重复新建,和套娃一样,但在窗口拉出对象后,会给属性赋值。那我们就利用属性功能添加一些代码进去:
//==========字段(私有,每个对象都是独立的个体)
//static UInt32 ledNO ;//led灯编号,//不能static,会被认为同一个使用。只能用于卖车票
private UInt32 ledNO;//led灯编号
//==========属性(套娃模式,设置对象字段)可以脑补一下套娃场景
[Category("led灯编号")]
[Description("第几个led灯")]
public UInt32 LedNO
{
get { return ledNO; }
set
{
ledNO = value;
//派生出来的儿子,给LedNO赋值,就会执行属性里的语句
label1.Text = "LED灯"+ledNO.ToString().PadLeft(3, '0') + ':';
}
}
这样我们看下效果:
//到这里,我们拖控件出来,给led编号赋值,控件的label1.text就会显示效果。
//=====================================
//这里复习一下思路,最里面的套娃,他的字段是私有的,他外面的儿子是不能读取基类字段,因为是private修饰的。留给你的只有public属性,我们可以利用属性的特点,在属性里加入我们想要的代码,这样每次拖控件出来,就相当于派生出来一个儿子。这个儿子的字段和其他儿子的字段是独立的个体。利用属性赋值来修改字段。
下面我们要考虑和plc连接了。plc主要是定时刷新数据,读取plc的led灯的状态,和开关写plc状态
我们需要在Form项目里引用里添加dll这样的库,没这个库就不能利用以太网连接plc
在plc下》引用》右键,管理NuGet程序包》
在里面搜下连接plc的库,比如xktcomm把它装上就可以了。
在程序里new一个库的对象出来。
//==================================
下面我们开始。
搜xktcomm,如果搜不到怎么办?
我们点一下齿轮。
点加号 + 新建一个。在源里输入: https://www.nuget.org/api/v2/
再点确定。这样就差不多了,再去搜下plc的库
//把这个喜课堂的库加进去。(plc库不止这一个,还有很多。只是这个库还比较好用。)
装好后,在右边引用里就能看见,已经有这个库了。如果能搜到xktcomm,但是装不上,那把程序包源里选叉号,删除多余的项,只保留https://www.nuget.org/api/v2/
//=====================================
在主程序里开始写代码
在Form1类内,新建xktcomm实例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using xktComm.Common;
namespace plc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private xktComm.SiemensS7 s7200s = new xktComm.SiemensS7();
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DataSource = Enum.GetNames(typeof (CPU_Type));
comboBox1.SelectedIndex = 1;//指向200smart
}
private void button1_Click(object sender, EventArgs e)
{
string ip = textBox1.Text;
//ip地址,cpu型号,站号,插槽号
//!成功
//if (!s7200s.Connect(ip, xktComm.Common.CPU_Type.S7200SMART, 0, 0))
if (!s7200s.Connect(ip, (CPU_Type)Enum.Parse(typeof(CPU_Type),comboBox1.Text),
Convert.ToInt32(textBox2.Text), Convert.ToInt32(textBox2.Text)))
{
MessageBox.Show("没找到cpu", "失败");
}
else
{//成功
button1.BackColor = Color.Green;
}
}
}
}
看下效果:
//我没硬件plc,那接着再修饰下控件,加个定时器刷新led状态
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using xktComm.Common;
namespace plc
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//================实例对象
private xktComm.SiemensS7 s7200s = new xktComm.SiemensS7();
Timer tim1 = new Timer();
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DataSource = Enum.GetNames(typeof (CPU_Type));
comboBox1.SelectedIndex = 1;//指向200smart
tim1.Tick += tim1_Click; //绑定一个事件
}
private void button1_Click(object sender, EventArgs e)
{
string ip = textBox1.Text;
//ip地址,cpu型号,站号,插槽号
//!成功
//if (!s7200s.Connect(ip, xktComm.Common.CPU_Type.S7200SMART, 0, 0))
if (!s7200s.Connect(ip, (CPU_Type)Enum.Parse(typeof(CPU_Type),comboBox1.Text),
Convert.ToInt32(textBox2.Text), Convert.ToInt32(textBox2.Text)))
{
MessageBox.Show("没找到cpu", "失败");
}
else
{//成功
button1.BackColor = Color.Green;
tim1.Interval = 500;//毫秒
tim1.Start(); //定时器开
}
}
private void tim1_Click(object sender, EventArgs e)
{ //定时循环
//s7200s.ReadBytes()
//led1.Ledstart =(bool) s7200s.Read(led1.LedAddress1, VarType.Bit);
//套娃控件
foreach (var item in Controls)//剥离出控件
{
if (item is LED.led app)//取出控件
{
app.Ledstart= (bool)s7200s.Read(led1.LedAddress1, VarType.Bit);
}
}
}
}
}
下面写开关写PLC