动态可订制属性的 PropertyGrid(转载)
参考: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(转载)相关推荐
- 动态可订制属性的 PropertyGrid
文章转载,原文来自:http://blog.csdn.net/akron/article/details/2750566 在VB6, VC++, C#.net 里都可以见到一个属性设计器,用来编辑修改 ...
- EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性
创建动态查询 想在项目中实现一个灵活的动态查询类,参考http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html和http://www.cnb ...
- jquery动态改变onclick属性导致失效的问题解决方法
onclick属性失效的问题,相信很多的朋友都有遇到过吧,jquery动态改变onclick属性就会导致此问题的发生,解决方法如下,希望对大家有所帮助 代码如下: <li id="&q ...
- Silverlight学习笔记三(鼠标点击动态画直线|动态设置Ellipse的Canvas.Top与Canvas.Left|动态设置Stroke属性的方法。)...
我有可能需要把AutoCAD的部分功能搬到浏览器上,先练习一下画直线的方法.如图: MainPage.xaml代码: 大气象 <UserControl x:Class="DrawLin ...
- java 反射 设置属性_Java通过反射机制动态设置对象属性值的方法
/** * MethodName: getReflection * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7- ...
- java动态删除属性值_JavaBean动态添加删除属性
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.cglib BeanGenerator beanGenerator = new BeanGenerator(); beanGenerator.addP ...
- Vue动态设置Style属性
Vue动态设置Style属性_fuzhongbin的博客-CSDN博客_vue 动态style :style="{ color:domain.groups == 1? '#ccc': dom ...
- python 类装饰器和继承_python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)...
介绍装饰器.继承.元类.mixin,四种給类动态添加类属性和方法的方式 有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加. 1 #coding= ...
- django的view中或者前台中动态的添加属性
1.view中动态的添加属性,到时候这个queryset集合就有了添加的属性,前台就可以获取数据了 news_info = NewsInfo.objects.all() for new_info in ...
最新文章
- JPA保存数据自动加入创建人,修改人
- 笔记:编写高质量代码 改善Java程序的151个建议
- Android 欢迎页面的编写
- Python的小特别
- graphql入门_GraphQL入门指南
- middlegenidenbsp;nbsp;eclipsenbsp;的插件
- 如何在.NET Core中创建API
- 技巧 | 在R语言中使用高德地图的API进行地理/逆地理编码(地址与经纬度的相互转换)...
- Scrapy开发指南
- 股票冲高回落意味着什么?
- 解析深度学习:语音识别实践 (俞栋等著) 完整pdf[44MB]
- Linux 系统磁盘满处理方法
- ie 无人操作自动关闭_Win10系统下ie浏览器无响应白屏自动关闭如何修复
- 信息系统项目管理师必背核心考点(二十六)三点估算(PERT)
- 001 【Chrome】浏览器自带取色器
- 重点推荐:看乾隆“上书房”求学记,哈哈
- 精细化用电侧能源管控 解码光伏电站运维痛点
- 无须注册的云盘平台anonfile
- 制作 macOS High Sierra U盘
- 耳机插入电脑没反应 控制面板也找不到realtek音频管理器的解决方案
热门文章
- docker基础知识之挂载本地目录
- Google 超分辨率技术 RAISR:模糊图片瞬间变清晰,运算速度快十倍
- SVD分解的并行实现
- yii2使用select2
- 第一季度Teradata营收下降7.3% 利润下跌63%
- 十 Appium环境搭建(Windows版)
- 移动物联网技术LoRa、SigFox、NB-IoT和eMTC的发展轨迹
- ubuntu12.04中sublime输入中文
- Adobe Flash Player 10.0.32.18
- 可侦测多种眼疾的AI 系统 对不熟悉眼科的医疗照护人员极有帮助