参考:http://bbs.csdn.net/topics/380095345

参考:http://bbs.csdn.net/topics/390331033

转自:http://blog.csdn.net/akron/article/details/2750566

版权声明:本文为博主原创文章,未经博主允许不得转载。

在VB6, VC++, C#.net 里都可以见到一个属性设计器,用来编辑修改 object 的属性。C# 下提供了一个属性设计器 PropertyGrid, 其使用极其简单,只要

grid.SelectedObject = myOjbect;

就可以把myOjbect 的所有属性显示出来。不过很多时候我们不希望如此,因为欠缺一种灵活性。我希望可以自由的控制需要编辑的内容。能做的这一点,再配合可编辑的 ListView, 可以很好的解决复杂内容的修改编辑问题。

首先是定义一个CProperty, 用来设置 object 在PropertyGrid 中的内容, 还得定义一个实现ICustomTypeDescriptor 接口的容器CPropertyCollection, 最后定制一个 PropertyDescriptor, 用来描述 PropertyGrid 接口方法。

public class CPropertyCollection : CCollection<CProperty>, ICustomTypeDescriptor

{

public void Add(CProperty value)

{

base.Put(value.Name, value);

}

#region "TypeDescriptor"

public String GetClassName()

{

return TypeDescriptor.GetClassName(this, true);

}

public AttributeCollection GetAttributes()

{

return TypeDescriptor.GetAttributes(this, true);

}

public String GetComponentName()

{

return TypeDescriptor.GetComponentName(this, true);

}

public TypeConverter GetConverter()

{

return TypeDescriptor.GetConverter(this, true);

}

public EventDescriptor GetDefaultEvent()

{

return TypeDescriptor.GetDefaultEvent(this, true);

}

public PropertyDescriptor GetDefaultProperty()

{

return TypeDescriptor.GetDefaultProperty(this, true);

}

public object GetEditor(Type editorBaseType)

{

return TypeDescriptor.GetEditor(this, editorBaseType, true);

}

public EventDescriptorCollection GetEvents(Attribute[] attributes)

{

return TypeDescriptor.GetEvents(this, attributes, true);

}

public EventDescriptorCollection GetEvents()

{

return TypeDescriptor.GetEvents(this, true);

}

public PropertyDescriptorCollection GetProperties(Attribute[] attributes)

{

PropertyDescriptor[] propDes = new PropertyDescriptor[this.Count];

for (int i = 0; i < this.Count; i++) {

CProperty prop = (CProperty) this[i];

propDes[i] = new CPropertyDescriptor(ref prop, attributes);

}

return new PropertyDescriptorCollection(propDes);

}

public PropertyDescriptorCollection GetProperties()

{

return TypeDescriptor.GetProperties(this, true);

}

public object GetPropertyOwner(PropertyDescriptor pd)

{

return this;

}

#endregion

}

public class CProperty

{

private string m_Name = string.Empty;

private bool m_bReadOnly = false;

private bool m_bVisible = true;

private object m_Value = null;

private string m_Category = string.Empty;

TypeConverter m_Converter = null;

object m_Editor = null;

public CProperty(string name, object value)

{

m_Name = name;

m_Value = value;

}

public CProperty(string name, object value, bool bReadOnly, bool bVisible)

{

m_Name = name;

m_Value = value;

m_bReadOnly = bReadOnly;

m_bVisible = bVisible;

}

public bool ReadOnly

{

get { return m_bReadOnly; }

set { m_bReadOnly = value; }

}

public virtual TypeConverter Converter

{

get { return m_Converter; }

set { m_Converter = value; }

}

public string Name

{

get { return m_Name; }

set { m_Name = value; }

}

public bool Visible

{

get { return m_bVisible; }

set { m_bVisible = value; }

}

public virtual object Value

{

get { return m_Value; }

set { m_Value = value; }

}

public string Category

{

get { return m_Category; }

set { m_Category = value; }

}

public virtual object Editor

{

get { return m_Editor; }

set { m_Editor = value;  }

}

}

public class CPropertyDescriptor : PropertyDescriptor

{

CProperty m_Property;

public CPropertyDescriptor(ref CProperty property, Attribute[] attrs)

: base(property.Name, attrs)

{

m_Property = property;

}

#region PropertyDescriptor "region"

public override bool CanResetValue(object component)

{

return false;

}

public override Type ComponentType

{

get { return null; }

}

public override object GetValue(object component)

{

return m_Property.Value;

}

public override string Description

{

get { return m_Property.Name; }

}

public override string Category

{

get { return m_Property.Category; }

}

public override string DisplayName

{

get { return m_Property.Name; }

}

public override bool IsReadOnly

{

get { return m_Property.ReadOnly; }

}

public override TypeConverter Converter

{

get { return m_Property.Converter; }

}

public override void ResetValue(object component)

{

}

public override bool ShouldSerializeValue(object component)

{

return false;

}

public override void SetValue(object component, object value)

{

m_Property.Value = value;

}

public override Type PropertyType

{

get { return m_Property.Value.GetType(); }

}

public override object GetEditor(Type editorBaseType)

{

return m_Property.Editor == null ? base.GetEditor(editorBaseType) : m_Property.Editor;

}

#endregion

}

下面的事情变得很简单:

private void Form_Load(object sender, EventArgs e)

{

CProperty myProp1 = new CProperty("Test1", "test");

MyProp1.Category = "test";

CProperty myProp2 = new CProperty("Test2", 1);

myProp2.Editor = new System.Drawing.Design.ColorEditor();

myProperties.Add(myProp1);

myProperties.Add(myProp2);

grid.SelectedObject = myProperties;

}

可以看到通过CProperty.Editor 可以使用各种的编辑器,甚至自定义的编辑器(从 UITypeEditor 派生,msdn中有例子)。另一个要点是CProperty.Converter, 用来自定义如何进行类型转换,例如,enum 类型在PropertyGrid 中用 List 编辑,如果不想事先定义一个 enum, 可以用自己的 TypeConverter 来实现功能更强大的编辑方法。

public class ListConverter : StringConverter

{

object[] m_Objects;

public ListConverter(object[] objects)

{

m_Objects = objects;

}

public override bool GetStandardValuesSupported(ITypeDescriptorContext context)

{

return true;

}

public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)

{

return true;

}

public override

System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)

{

return new StandardValuesCollection(m_Objects);

}

}

使用ListConverter:

CProperty myProp = new CProperty("Test", "test2");

myProp.Converter = new ListConverter(new string[] { "test1", "test2","test3" });

当click 属性 Test 时,会弹出一个 List 框。重载 TypeConverter 的 ConvertTo and ConvertFrom 可以获得更多的功能。

转载于:https://www.cnblogs.com/Joetao/articles/5432316.html

动态可订制属性的 PropertyGrid(转载)相关推荐

  1. 动态可订制属性的 PropertyGrid

    文章转载,原文来自:http://blog.csdn.net/akron/article/details/2750566 在VB6, VC++, C#.net 里都可以见到一个属性设计器,用来编辑修改 ...

  2. EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性

    创建动态查询 想在项目中实现一个灵活的动态查询类,参考http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html和http://www.cnb ...

  3. jquery动态改变onclick属性导致失效的问题解决方法

    onclick属性失效的问题,相信很多的朋友都有遇到过吧,jquery动态改变onclick属性就会导致此问题的发生,解决方法如下,希望对大家有所帮助 代码如下: <li id="&q ...

  4. Silverlight学习笔记三(鼠标点击动态画直线|动态设置Ellipse的Canvas.Top与Canvas.Left|动态设置Stroke属性的方法。)...

    我有可能需要把AutoCAD的部分功能搬到浏览器上,先练习一下画直线的方法.如图: MainPage.xaml代码: 大气象 <UserControl x:Class="DrawLin ...

  5. java 反射 设置属性_Java通过反射机制动态设置对象属性值的方法

    /** * MethodName: getReflection * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7- ...

  6. java动态删除属性值_JavaBean动态添加删除属性

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.cglib BeanGenerator beanGenerator = new BeanGenerator(); beanGenerator.addP ...

  7. Vue动态设置Style属性

    Vue动态设置Style属性_fuzhongbin的博客-CSDN博客_vue 动态style :style="{ color:domain.groups == 1? '#ccc': dom ...

  8. python 类装饰器和继承_python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)...

    介绍装饰器.继承.元类.mixin,四种給类动态添加类属性和方法的方式 有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加. 1 #coding= ...

  9. django的view中或者前台中动态的添加属性

    1.view中动态的添加属性,到时候这个queryset集合就有了添加的属性,前台就可以获取数据了 news_info = NewsInfo.objects.all() for new_info in ...

最新文章

  1. JPA保存数据自动加入创建人,修改人
  2. 笔记:编写高质量代码 改善Java程序的151个建议
  3. Android 欢迎页面的编写
  4. Python的小特别
  5. graphql入门_GraphQL入门指南
  6. middlegenidenbsp;nbsp;eclipsenbsp;的插件
  7. 如何在.NET Core中创建API
  8. 技巧 | 在R语言中使用高德地图的API进行地理/逆地理编码(地址与经纬度的相互转换)...
  9. Scrapy开发指南
  10. 股票冲高回落意味着什么?
  11. 解析深度学习:语音识别实践 (俞栋等著) 完整pdf[44MB]
  12. Linux 系统磁盘满处理方法
  13. ie 无人操作自动关闭_Win10系统下ie浏览器无响应白屏自动关闭如何修复
  14. 信息系统项目管理师必背核心考点(二十六)三点估算(PERT)
  15. 001 【Chrome】浏览器自带取色器
  16. 重点推荐:看乾隆“上书房”求学记,哈哈
  17. 精细化用电侧能源管控 解码光伏电站运维痛点
  18. 无须注册的云盘平台anonfile
  19. 制作 macOS High Sierra U盘
  20. 耳机插入电脑没反应 控制面板也找不到realtek音频管理器的解决方案

热门文章

  1. docker基础知识之挂载本地目录
  2. Google 超分辨率技术 RAISR:模糊图片瞬间变清晰,运算速度快十倍
  3. SVD分解的并行实现
  4. yii2使用select2
  5. 第一季度Teradata营收下降7.3% 利润下跌63%
  6. 十 Appium环境搭建(Windows版)
  7. 移动物联网技术LoRa、SigFox、NB-IoT和eMTC的发展轨迹
  8. ubuntu12.04中sublime输入中文
  9. Adobe Flash Player 10.0.32.18
  10. 可侦测多种眼疾的AI 系统 对不熟悉眼科的医疗照护人员极有帮助