c#——Winform PropertyGrid使用
来源:互联网 发布:彩票号码组合软件 编辑:程序博客网 时间:2024/06/05 05:36
最近被迫调到某部,协助一个配置工具的开发。
做winform的开发,这些控件相关的知识还是在学校上课的时候学到的。工作之后,没有接触相关的开发。
使用的是SCSF框架,控件使用winform自带控件。但是界面功能要求比较复杂。
一开始上手,还是有些困难,同时也有些排斥。但是一想自己这么痛苦,其实就是自己的基础不扎实。慢慢的放松了对自己的要求。
任何事情,做就做好。不得不做的时候,就努力做到最好的样子,争取从中学到一些知识,而不仅仅是完成任务。
不多说,调整心态,积累一些开发过程的经验。
这里学到大量的重载 和 扩展,以前一般只用其本身的功能。慢慢适应,如何扩展得到自己想要的效果。
要求使用propertyGrid
- 动态显示不同的属性列表
- 属性列表顺序已有定义
- 属性名称显示中文。
简单说一下解决方案:
- 第一点使用对象动态绑定到控件即可
- 第二点需要设置控件属性中的PropertySort为NoSort,这样就会使用绑定对象的属性顺序,即达到自定义属性列表的顺序
- 第三点这个需要重写Attribute方法,否则无法实现,显示中文。因为默认显示属性字段的名称
下面讲一下具体的实现过程
首先需要写一个新的Attribute,重载一些方法,使得能够改变属性展示名称的来源。
代码如下:
using System;namespace Jurassic.AdapterConfig.FileEntityRetrieveModule.Services.Model{ public class MyControlAttibute : Attribute { private readonly string _categoryName; private readonly string _propertyName; private readonly string _propertyDescription; private readonly object _defaultValue; public MyControlAttibute(string categoryName, string name, string description, object defalutValue) { _categoryName = categoryName; this._propertyName = name; this._propertyDescription = description; this._defaultValue = defalutValue; } public MyControlAttibute(string categoryName, string name, string description) { this._propertyName = name; this._propertyDescription = description; _categoryName = categoryName; this._defaultValue = ""; } public MyControlAttibute(string categoryName, string name) { this._propertyName = name; _categoryName = categoryName; this._propertyDescription = ""; this._defaultValue = ""; } public MyControlAttibute(string name) { this._propertyName = name; _categoryName = ""; this._propertyDescription = ""; this._defaultValue = ""; } public string CategoryName { get { return this._categoryName; } } public string PropertyName { get { return this._propertyName; } } public string PropertyDescription { get { return this._propertyDescription; } } public object DefaultValue { get { return this._defaultValue; } } }}
写一个PropertyBase继承自System.ComponentModel的ICustomTypeDescriptor。提供为对象提供动态自定义类型信息的接口
所有绑定的对象类都需要继承PropertyBase类
代码如下
public class PropertyBase : ICustomTypeDescriptor { /// <summary> /// 下面这段代码来源于:http://www.bluespace.cn/Html/Csdn/2_47/View_4702219.html /// </summary> /// <returns></returns> #region ICustomTypeDescriptor 显式接口定义 AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } string ICustomTypeDescriptor.GetClassName() { return TypeDescriptor.GetClassName(this, true); } string ICustomTypeDescriptor.GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } TypeConverter ICustomTypeDescriptor.GetConverter() { return TypeDescriptor.GetConverter(this, true); } EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return null; } object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { ArrayList props = new ArrayList(); Type thisType = this.GetType(); PropertyInfo[] pis = thisType.GetProperties(); foreach (PropertyInfo p in pis) { if (p.DeclaringType == thisType || p.PropertyType.ToString() == "System.Drawing.Color") { //判断属性是否显示 var browsable = (BrowsableAttribute)Attribute.GetCustomAttribute(p, typeof(BrowsableAttribute)); if (browsable != null) { if (browsable.Browsable == true || p.PropertyType.ToString() == "System.Drawing.Color") { var psd = new PropertyStub(p, attributes); props.Add(psd); } } else { var psd = new PropertyStub(p, attributes); props.Add(psd); } } } var propArray = (PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)); return new PropertyDescriptorCollection(propArray); } object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return this; } #endregion }
上面的类中需要调用PropertyStub,继承自System.ComponentModel的PropertyDescriptor
代码如下
public class PropertyStub : PropertyDescriptor { PropertyInfo info; public PropertyStub(PropertyInfo propertyInfo, Attribute[] attrs) : base(propertyInfo.Name, attrs) { this.info = propertyInfo; } public override Type ComponentType { get { return this.info.ReflectedType; } } public override bool IsReadOnly { get { return this.info.CanWrite == false; } } public override Type PropertyType { get { return this.info.PropertyType; } } public override bool CanResetValue(object component) { return false; } public override object GetValue(object component) { try { return this.info.GetValue(component, null); } catch { return null; } } public override void ResetValue(object component) { } public override void SetValue(object component, object value) { this.info.SetValue(component, value, null); } public override bool ShouldSerializeValue(object component) { return false; } //通过重载下面这个属性,可以将属性在PropertyGrid中的显示设置成中文 public override string DisplayName { get { if (info != null) { var uicontrolattibute = (MyControlAttibute)Attribute.GetCustomAttribute(info, typeof(MyControlAttibute)); if (uicontrolattibute != null) return uicontrolattibute.PropertyName; return info.Name; } return ""; } } public override string Category { get { if (info != null) { var uicontrolattibute = (MyControlAttibute)Attribute.GetCustomAttribute(info, typeof(MyControlAttibute)); if (uicontrolattibute != null) return uicontrolattibute.CategoryName; return info.Name; } return ""; } } public override string Description { get { if (info != null) { var uicontrolattibute = (MyControlAttibute)Attribute.GetCustomAttribute(info, typeof(MyControlAttibute)); if (uicontrolattibute != null) return uicontrolattibute.PropertyDescription; return info.Name; } return ""; } } }
以上三步就做好的基础的工作,然后就编写绑定的基础类
using System.ComponentModel;namespace Jurassic.AdapterConfig.FileEntityRetrieveModule.Services.Model{ /// <summary> /// 实体抓取逻辑 DB 配置信息 /// </summary> public class DbRetrieveConfig : PropertyBase { private string _connectionStr; private string _tableName; private string _fieldName; private string _sql; [ MyControlAttibute("实体抓取逻辑(DB Blob)","数据库连接", "设置数据库连接字符串")] public string ConnectionStr { get { return _connectionStr; } set { if (!string.IsNullOrEmpty(value)) { _connectionStr = value.Trim(); } } } [ MyControlAttibute("实体抓取逻辑(DB Blob)", "表名称", "获取或设置数据库表名称")] public string TableName { get { return _tableName; } set { if (!string.IsNullOrEmpty(value)) { _tableName = value.Trim(); } } } [MyControlAttibute("实体抓取逻辑(DB Blob)", "表字段", "获取或设置数据库表字段")] public string FieldName { get { return _fieldName; } set { if (!string.IsNullOrEmpty(value)) { _fieldName = value.Trim(); } } } [ MyControlAttibute("实体抓取逻辑(DB Blob)", "SQL", "获取或设置执行的SQL语句")] public string Sql { get { return _sql; } set { if (!string.IsNullOrEmpty(value)) { _sql = value.Trim(); } } } }}
using System.ComponentModel;namespace Jurassic.AdapterConfig.FileEntityRetrieveModule.Services.Model{ /// <summary> /// 实体抓取逻辑 FTP 配置信息 /// </summary> public class FtpRetriveConfig : PropertyBase { private string _iP; private string _userName; private string _pwd; private int _port; private string _filePath; [MyControlAttibute("实体抓取逻辑(FTP)", "服务器", "获取或设置服务器IP地址")] public string IP { get { return _iP; } set { if (!string.IsNullOrEmpty(value)) { _iP = value.Trim(); } } } [MyControlAttibute("实体抓取逻辑(FTP)", "端口", "获取或设置服务器端口")] public int Port { get { return _port; } set { _port = value; } } [MyControlAttibute("实体抓取逻辑(FTP)", "用户名", "获取或设置用户名")] public string UserName { get { return _userName; } set { if (!string.IsNullOrEmpty(value)) { _userName = value.Trim(); } } } [MyControlAttibute("实体抓取逻辑(FTP)", "密码", "获取或设置密码")] public string Pwd { get { return _pwd; } set { if (!string.IsNullOrEmpty(value)) { _pwd = value.Trim(); } } } [MyControlAttibute("实体抓取逻辑(FTP)", "文件路径", "获取或设置实体存放的文件路径")] public string FilePath { get { return _filePath; } set { if (!string.IsNullOrEmpty(value)) { _filePath = value.Trim(); } } } }}
以上定义了两个实体类,并且都继承PropertyBase。而且使用自定义的MyAttribute属性。
一切准备就绪,接下来就是数据绑定喽!
真不容易哦
在view中调用
public void SetPropertyGridData(string type, PropertyBase connection) { this.tlscboStoragType.Text = type; this.propgrdEntityRetrieve.SelectedObject = connection; }
将两种实体类传过来就可以动态展示喽
最后一步,设置属性PropertySort为NoSort
这样,我们最后看一下展示的效果哦
1.
2.
1 0
- c#——Winform PropertyGrid使用
- c#——Winform PropertyGrid使用(二)
- winform propertygrid用法
- PropertyGrid使用
- Ext属性表格控件——PropertyGrid
- 探索PropertyGrid的使用
- PropertyGrid控件的使用
- 在PropertyGrid使用JsonStore
- propertygrid easyui 的使用
- C#WinForm控件使用
- propertygrid
- PropertyGrid
- 关于PropertyGrid的使用几篇好文
- PropertyGrid控件的使用1
- PropertyGrid控件的使用2
- PropertyGrid控件的使用3
- PropertyGrid控件的使用4
- PropertyGrid控件的使用5
- CC2540/CC2541/CC254x之OSAL操作系统抽象层
- Android中的URL Scheme
- **PHP** 多维数组和日期
- 数据结构与算法总结4_排序算法
- Thread中的uncheckedException的处理
- c#——Winform PropertyGrid使用
- Different Ways to Add Parentheses
- Anatomy of an Elasticsearch Cluster part.1——深度解析ElasticSearch(1)
- VS2013 多个项目添加引用
- pthread_join与pthread_deatch和分离线程的关系
- 理解JVM——Java内存区域
- J2EE
- 选择(select)排序算法
- git使用简明教程