C#制作Wincc组件进行配方管理(二)

连接: C#制作Wincc组件进行配方管理(一)

7,在设计过程中碰到以下几个问题亟待解决;

                  q1: 使用Appconfig来进行保存Plc的信息.

                  q2:数据绑定和DataSource的研究和使用.

                  q3:DataGridView的自定义---左侧名称和序号.然后每个格子进行特殊设定.比如范围等.

                  q4:使用 导入导出式的方式自定义plc配方类,来进行自由设定的配方数据.

                  q5:使用组件进行测试是否成功.

 

7.q1:

          解决方法1:使用config配置文件和创建的config类. 查看链接1,查看链接2

          解决方法2:使用自定义的xml文件的方式.查看链接

8,  终于制作成功了:

image

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文件.可以通过找到,也可以通过自定义的一个位置进行.再那里进行设定.

原文地址:https://www.cnblogs.com/frogkiller/p/12378473.html