C#制作Wincc组件进行配方管理(二)
7,在设计过程中碰到以下几个问题亟待解决;
q1: 使用Appconfig来进行保存Plc的信息.
q2:数据绑定和DataSource的研究和使用.
q3:DataGridView的自定义---左侧名称和序号.然后每个格子进行特殊设定.比如范围等.
q4:使用 导入导出式的方式自定义plc配方类,来进行自由设定的配方数据.
q5:使用组件进行测试是否成功.
7.q1:
解决方法1:使用config配置文件和创建的config类. 查看链接1,查看链接2
解决方法2:使用自定义的xml文件的方式.查看链接
8, 终于制作成功了:
9,这个项目的一些思考.
1,xml文件的读取.主要是App.config的读取.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="PLC" type="RecipeControl.PlcInfoSection,RecipeControl" /> </configSections> <connectionStrings> <add name="RecipeControl.Properties.Settings.abcConnectionString" connectionString="Data Source=.\WINCC;Initial Catalog=abc;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <PLC configSource="PLC.xml" /> </configuration>
注意, configSections必须在 最上面.另外PLC.xml必须在exe所在的文件夹下.
<PLC> <PLCInfos> <PLCItem TYPE="S71200" IP="192.168.0.123" Rack="0" Slot="1" DataType ="DataBlock" DB="1" Start="0"/> <PLCItem TYPE="S71200" IP="192.168.0.124" Rack="0" Slot="1" DataType ="DataBlock" DB="1" Start="0"/> <PLCItem TYPE="S71200" IP="192.168.0.125" Rack="0" Slot="1" DataType ="DataBlock" DB="1" Start="0"/> <PLCItem TYPE="S71200" IP="192.168.0.126" Rack="0" Slot="1" DataType ="DataBlock" DB="1" Start="0"/> </PLCInfos> </PLC>
2,建立3个类来进行模型匹配
Collection类,相当于是PLCInfos节点.
public class PlcInfoSection : ConfigurationSection { [ConfigurationProperty("PLCInfos", IsDefaultCollection = true)] public PlcInofsCollection PLCInfos { get { return (PlcInofsCollection)base["PLCInfos"]; // 子列表节点 } } }
public class PlcInofsCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new PlcInfoElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((PlcInfoElement)element).Name; // 指定AA属性为唯一索引 } public override ConfigurationElementCollectionType CollectionType { get { return ConfigurationElementCollectionType.BasicMap; } } protected override string ElementName { get { return "PLCItem"; // 子节点名称 } } } public class PlcInfoElement : ConfigurationElement { [ConfigurationProperty("Name", IsRequired = true)] // 是否必填 public string Name { get { return (string)base["Name"]; // 节点属性名称 } } [ConfigurationProperty("TYPE", IsRequired = true)] // 是否必填 public CpuType TYPE { get { return (CpuType)base["TYPE"]; // 节点属性名称 } } [ConfigurationProperty("IP", IsRequired = true)] // 是否必填 public string IP { get { return (string)base["IP"]; // 节点属性名称 } } [ConfigurationProperty("Rack", IsRequired = true)] // 是否必填 public short Rack { get { return (short)base["Rack"]; // 节点属性名称 } } [ConfigurationProperty("Slot", IsRequired = true)] // 是否必填 public short Slot { get { return (short)base["Slot"]; // 节点属性名称 } } [ConfigurationProperty("DataType", IsRequired = true)] // public DataType DataType { get { return (DataType)base["DataType"]; // 节点属性名称 } } [ConfigurationProperty("DB", IsRequired = true)] // public int DB { get { return (int)base["DB"]; // 节点属性名称 } } [ConfigurationProperty("Start", IsRequired = true)] // public int Start { get { return (int)base["Start"]; // 节点属性名称 } } }
,然后进行数据读取---即可进行迭代操作.
List<PlcInfoElement> listbox1Source =
(from PlcInfoElement element in RecipeHelper.PlcSeciton.PLCInfos
select element).ToList();
3,数据绑定:
1,datasource 绑定到 bindingLIst或者bindSource类,进行数据的更新
2,属性绑定: 使用
dataGridView1.DataBindings.Add("Enabled", controlStatus, "PLCStatus", false, DataSourceUpdateMode.OnPropertyChanged); listBox1.DataBindings.Add("Enabled", controlStatus, "PLCStatus", false, DataSourceUpdateMode.OnPropertyChanged); checkBox1.DataBindings.Add("Enabled", controlStatus, "PLCStatus", false, DataSourceUpdateMode.OnPropertyChanged); button1.DataBindings.Add("Enabled", controlStatus, "PLCStatus", false, DataSourceUpdateMode.OnPropertyChanged); button2.DataBindings.Add("Enabled", controlStatus, "PLCStatus", false, DataSourceUpdateMode.OnPropertyChanged); ResultBox.DataBindings.Add("Text", controlStatus, "Result", false, DataSourceUpdateMode.OnPropertyChanged);
3,属性绑定之后,使用一个INotifyPropertyChanged 的接口进行绑定.
public class RecipeControlStatus : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; //----读写互锁 private bool m_PlcCommand = true; private string m_result = string.Empty; public bool PLCStatus { get { return m_PlcCommand; } set { m_PlcCommand = value; OnPropertyChanged("PLCStatus"); } } public string Result { get { return m_result; } set { m_result = value; OnPropertyChanged("Result"); } } public void OnPropertyChanged(string name) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } }
绑定之后有3中模式,
Never, 数据不会主动写入.
OnValiDate 当焦点转移时变化
OnPropertyChanged 实时同步
4,使用checkbox和checklist进行多个plc的操作.
5,使用linq to sql 绑定数据库,进行数据库数据的读写.
6,源代码地址:https://gitee.com/mao_qin_bin/s7netplus.git
7,其他还未完成的一些事情.数据验证还有异步线程优化之类的.等以后再进行更新.
8,其实是可以进行config文件配置的.可以使用config.manager的方法.但是使用configsource好像总是会有问题.不知道是不是因为名称
不是全名称的缘故. 这个config文件是运行的系统的config文件.可以通过找到,也可以通过自定义的一个位置进行.再那里进行设定.