命名空间:netMarketing.winformHelper
功能:动态构建属性
功能详细说明:
propertyGridHelper类用来动态构建属性。XProp类代表一条属性,XProps是多个XProp的集合类。
这个类的优点在于可以动态设定propertyGrid控件的属性,传统的使用预定义标签与初始化代码实现的效果是固定的,是不可以增减的。
这个类也有一个缺点,就是不好使用Settings类将用户变动的属性值保存起来。
如果用序列化保存的话,仅仅是能再现用户修改,而要与程序其它部分的全局量关联起来,恐怕得人工编写接口代码,但这样就失去了自动化效果。
使用这个类构建的IO表类,可以很好的工作,下图IO表类的PropertyGrid界面就是由propertyGridHelper生成的。
常用函数列表:
/// 设定属性项目,传入List string, 每条属性项目是一个CSV格式的逗号分隔串 /// <para>逗号分隔项目依次表示:Name,Value,Category,Description,Combox项目(逗号分隔)</para> /// <para>最后一项:Combox项目,表示一个可选字符串列表。如果此项不存在,则传入空串</para> public void setPropertyItems(List<string> itemCSVStr) //按Category和Name取属性对象并赋值,找不到属性对象则抛异常 public void setValue(string Name,string Category, object value1) //按Category和Name取value,找不到属性对象抛异常 public object getValue(string Name, string Category)
参考例子:
这个类用法很简单。
先声明:
private propertyGridHelper pgrid = new propertyGridHelper();
接下来用下面代码初始化属性:
/// <summary> /// 初始化属性项目 /// </summary> private void initPropertyItem() { var dataAry = new List<string>(); //厚度表A dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"串口号", @"COM1", @"厚度表A配置", "指定串口号,例如COM1", serialHelper.GetMacPortList().getCommaString()})); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"速率", serialHelper.PortBaudRateList[1].ToString(), @"厚度表A配置", "串口速率,例如:9600,115200", serialHelper.PortBaudRateList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"校验位", serialHelper.ParityList[2], @"厚度表A配置", @"指定校验位,例如:Even,None,Odd", serialHelper.ParityList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"停止位", serialHelper.StopBitsList[0], @"厚度表A配置", @"指定停止位,例如:One,Two", serialHelper.StopBitsList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"数据位", serialHelper.DataBitsList[3].ToString(), @"厚度表A配置", @"指定停止位,例如:5,6,7,8", serialHelper.DataBitsList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); //厚度表B dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"串口号", @"COM2", @"厚度表B配置", "指定串口号,例如COM1", serialHelper.GetMacPortList().getCommaString()})); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"速率", serialHelper.PortBaudRateList[1].ToString(), @"厚度表B配置", "串口速率,例如:9600,115200", serialHelper.PortBaudRateList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"校验位", serialHelper.ParityList[2], @"厚度表B配置", @"指定校验位,例如:Even,None,Odd", serialHelper.ParityList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"停止位", serialHelper.StopBitsList[0], @"厚度表B配置", @"指定停止位,例如:One,Two", serialHelper.StopBitsList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"数据位", serialHelper.DataBitsList[3].ToString(), @"厚度表B配置", @"指定停止位,例如:5,6,7,8", serialHelper.DataBitsList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); //扫描器 dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"扫描器IP地址", @"192.168.1.1", @"扫码器配置", "指定扫码器的IP地址", "" })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"扫描器端口号", @"5000", @"扫码器配置", @"扫码器的端口号", "" })); //PLC dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"PLC IP地址", @"192.168.2.1", @"PLC通讯配置", "指定PLC的IP地址", "" })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"PLC端口号", @"5000", @"PLC通讯配置", "指定PLC的端口号", "" })); pgrid.setPropertyItems(dataAry); }
效果如下:
完整的演示例程
在例程中,你可以看到,即可以手工设置Xprops(XProp类代表一条属性,XProps是多个XProp的集合类)
也可以调用函数setPropertyItems() 进行Xprops的设定。
相对于传统的PropertyGrid以类加标签方式的定义,使用propertyGridHelper类可以非常容易,最重要的是,它非常灵活。
你可能对于下面createCSVRow()函数有点疑问,为什么不直接写上逗号分隔的字符串,而是要用这个函数生成逗号分隔的字符串。
这是因为在netMarketing类中,凡是逗号分隔串,都会使用CSVHelper类的方法createCSVRow()生成,而使用 explainCSVRow()分割。
这两个函数包含了逗号分隔的CSV文件的处理规则,当字符串本身包含逗号或者特殊信息时,也可以正确的按逗号分隔串(CSV逗号分隔串格式)进行处理。
如果见识过复杂的逗号分隔的CSV文件(比如淘宝的商品信息的CSV文件)的同学,应该知道,其商品描述信息中是一段几十K的html代码,如果不按一定CSV文件的规则来处理的话,很容易被错误处理成许多个字段,而实际上它只是一个字段。
CSVHelper.createCSVRow() CSVHelper.explainCSVRow()
using netMarketing.automation; using netMarketing.winformHelper; using sharClass; 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 propertyGridHelpeTest { public partial class Form1 : Form { private propertyGridHelper pgrid = new propertyGridHelper(); private propertyGridHelper.XProps xpropList = new propertyGridHelper.XProps(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { initPropertyItem(); this.propertyGrid1.SelectedObject = pgrid.Props; this.propertyGrid1.PropertySort=PropertySort.Categorized; this.propertyGrid1.PropertyValueChanged += PropertyGrid1_PropertyValueChanged; } private void PropertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { MessageBox.Show($"旧值:{e.OldValue}"); } /// <summary> /// 初始化属性项目 /// </summary> private void initPropertyItem() { var dataAry = new List<string>(); //厚度表A dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"串口号", @"COM1", @"厚度表A配置", "指定串口号,例如COM1", serialHelper.GetMacPortList().getCommaString()})); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"速率", serialHelper.PortBaudRateList[1].ToString(), @"厚度表A配置", "串口速率,例如:9600,115200", serialHelper.PortBaudRateList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"校验位", serialHelper.ParityList[2], @"厚度表A配置", @"指定校验位,例如:Even,None,Odd", serialHelper.ParityList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"停止位", serialHelper.StopBitsList[0], @"厚度表A配置", @"指定停止位,例如:One,Two", serialHelper.StopBitsList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"数据位", serialHelper.DataBitsList[3].ToString(), @"厚度表A配置", @"指定停止位,例如:5,6,7,8", serialHelper.DataBitsList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); //厚度表B dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"串口号", @"COM2", @"厚度表B配置", "指定串口号,例如COM1", serialHelper.GetMacPortList().getCommaString()})); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"速率", serialHelper.PortBaudRateList[1].ToString(), @"厚度表B配置", "串口速率,例如:9600,115200", serialHelper.PortBaudRateList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"校验位", serialHelper.ParityList[2], @"厚度表B配置", @"指定校验位,例如:Even,None,Odd", serialHelper.ParityList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"停止位", serialHelper.StopBitsList[0], @"厚度表B配置", @"指定停止位,例如:One,Two", serialHelper.StopBitsList.ToList().getCommaString() })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"数据位", serialHelper.DataBitsList[3].ToString(), @"厚度表B配置", @"指定停止位,例如:5,6,7,8", serialHelper.DataBitsList.ToList().ConvertAll(s => s.ToString()).getCommaString() })); //扫描器 dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"扫描器IP地址", @"192.168.1.1", @"扫码器配置", "指定扫码器的IP地址", "" })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"扫描器端口号", @"5000", @"扫码器配置", @"扫码器的端口号", "" })); //PLC dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"PLC IP地址", @"192.168.2.1", @"PLC通讯配置", "指定PLC的IP地址", "" })); dataAry.Add(CSVHelper.createCSVRow(new List<string>() { @"PLC端口号", @"5000", @"PLC通讯配置", "指定PLC的端口号", "" })); pgrid.setPropertyItems(dataAry); } private void updatePropList() { xpropList.Clear(); var tmp = new List<string>() { "PLC请求读SN信号", "PC扫码完成", "PLC请求A表测厚度", "PC读A表厚度完成", "PLC请求B表测厚完成", "PC读B表厚度完成", "联机信号", "厚度表A清零", "厚度表B清零", "表A下压完成", "表B下压完成", "无" }; var ioList = tmp.getCommaString(); propertyGridHelper.XProp xprop = new propertyGridHelper.XProp(); xprop.Name = "IO名称"; xprop.Value = ""; xprop.Category = "IO对象设置"; xprop.Description = "IO名称,程序调用IO即以这个名称进行调用"; xprop.ProType = typeof(String); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "IO点编号"; xprop.Value = 0; xprop.Category = "IO对象设置"; xprop.Description = "IO点编号,即IO卡硬件上的IO点编号"; xprop.ProType = typeof(ushort); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "IO类型"; xprop.Value = iotypeEnum.输入; xprop.Category = "IO对象设置"; xprop.Description = "IO类型,有输入IO或者输出IO两种"; xprop.ProType = typeof(iotypeEnum); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "IO排列索引"; xprop.Value = 0; xprop.Category = "IO对象设置"; xprop.Description = "IO排列索引,这个影响在IO测试面板上面的IO项目前置后置的排列次序。"; xprop.ProType = typeof(int); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "真空名称"; xprop.Value = ""; xprop.Category = "真空对象设置"; xprop.Description = "真空名称,程序中调用真空对象,即以此名称调用。"; xprop.ProType = typeof(String); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "真空输出IO"; xprop.Value = ""; xprop.Category = "真空对象设置"; xprop.Description = "真空输出IO,这里选择一个已有的IO对象。"; xprop.ProType = typeof(propertyGridHelper.MyComboItemConvert); xprop.Converter = new propertyGridHelper.MyComboItemConvert(ioList); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "真空达标IO"; xprop.Value = ""; xprop.Category = "真空对象设置"; xprop.Description = "真空达标IO,这里选择一个已有的IO对象。"; xprop.ProType = typeof(propertyGridHelper.MyComboItemConvert); xprop.Converter = new propertyGridHelper.MyComboItemConvert(ioList); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "真空排列索引"; xprop.Value = 0; xprop.Category = "真空对象设置"; xprop.Description = "真空排列索引,这个影响在IO测试面板上面的真空项目前置后置的排列次序。"; xprop.ProType = typeof(int); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "气缸名称"; xprop.Value = ""; xprop.Category = "气缸对象设置"; xprop.Description = "气缸名称,程序中调用气缸对象,即以此名称调用。"; xprop.ProType = typeof(String); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "气缸输出IO"; xprop.Value = ""; xprop.Category = "气缸对象设置"; xprop.Description = "气缸输出IO,这里选择一个已有的IO对象。"; xprop.ProType = typeof(propertyGridHelper.MyComboItemConvert); xprop.Converter = new propertyGridHelper.MyComboItemConvert(ioList); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "气缸原点IO"; xprop.Value = ""; xprop.Category = "气缸对象设置"; xprop.Description = "气缸原点IO,这里选择一个已有的IO对象。如果选择无,则表示没有气缸原点IO。"; xprop.ProType = typeof(propertyGridHelper.MyComboItemConvert); xprop.Converter = new propertyGridHelper.MyComboItemConvert(ioList); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "气缸动点IO"; xprop.Value = 0; xprop.Category = "气缸对象设置"; xprop.Description = "气缸动点IO,这里选择一个已有的IO对象。如果选择无,则表示没有气缸动点IO。"; xprop.ProType = typeof(propertyGridHelper.MyComboItemConvert); xprop.Converter = new propertyGridHelper.MyComboItemConvert(ioList); xprop.ReadOnly = false; xpropList.Add(xprop); xprop = new propertyGridHelper.XProp(); xprop.Name = "气缸排列索引"; xprop.Value = 0; xprop.Category = "气缸对象设置"; xprop.Description = "气缸排列索引,这个影响在IO测试面板上面的气缸项目前置后置的排列次序。"; xprop.ProType = typeof(int); xprop.ReadOnly = false; xpropList.Add(xprop); } public enum iotypeEnum { 输入, 输出 } private void button2_Click(object sender, EventArgs e) { updatePropList(); this.propertyGrid1.SelectedObject = xpropList; this.propertyGrid1.PropertySort = PropertySort.Categorized; this.propertyGrid1.PropertyValueChanged += PropertyGrid1_PropertyValueChanged1; } private void PropertyGrid1_PropertyValueChanged1(object s, PropertyValueChangedEventArgs e) { MessageBox.Show($"旧值:{e.OldValue}"); } } }
注意: 下载地址为csdn下载, 没办法改为0分下载,而且最小5分, 各位见谅.
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

