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文件.可以通過找到,也可以通過自定義的一個位置進行.再那里進行設定.