问题描述
之前发了一个帖子问题描述的太简单了给大家造成了误解这里重新开贴详细说明出于项目要求需要定义一个属性可以动态增加的类(比如说定义一个截面类,包含形状、半径、长度、宽度四个属性,其中形状枚举圆形和矩形两种,选择圆形时显示半径属性不显示长宽属性,选择矩形时显示长宽属性不显示半径属性。也就是说利用PropertyGrid控件展示该类的属性是,当选择圆形时PropertyGrid可以显示2个属性,选择矩形时PropertyGrid则显示3个属性,无论2个属性还是3个属性对应的是同一个实例)于是在网上找到的SetPropertyVisability函数可以对截面类的一个实例实现我要的功能。但是当我定义2个截面实例的时候,一个设为圆形一个设为矩形行,由于SetPropertyVisability函数利用了反射,所以当其中任意一个实例被修改,2个实例的可见属性个数永远一致,并由最后一次对某一实例的形状进行更改是的数值决定。这是我不希望的。有没有大神知道解决方法,谢谢了(分别建成2个类的改动太大了)下面贴代码和图说明问题类代码enumfaceType{circ,rect}classface{privatefaceTypeft=faceType.circ;[Category("类型"),Description("截面形状"),ReadOnlyAttribute(false),BrowsableAttribute(true)]publicfaceTypeFaceType{get{returnft;}set{ft=value;if(ft==faceType.circ){SetPropertyVisability(this,"R",true);SetPropertyVisability(this,"L",false);SetPropertyVisability(this,"W",false);}else{SetPropertyVisability(this,"R",false);SetPropertyVisability(this,"L",true);SetPropertyVisability(this,"W",true);}}}privateintr=0;[Category("数据"),Description("半径"),ReadOnlyAttribute(false),BrowsableAttribute(true)]publicintR{get{returnr;}set{r=value;}}privateintl=0;[Category("数据"),Description("长度"),ReadOnlyAttribute(false),BrowsableAttribute(false)]publicintL{get{returnl;}set{l=value;}}privateintw=0;[Category("数据"),Description("宽度"),ReadOnlyAttribute(false),BrowsableAttribute(false)]publicintW{get{returnw;}set{w=value;}}///<summary>设置属性的可见性</summary>/// <param name="obj">属性所属的类</param>/// <param name="propertyName">属性名</param>/// <param name="visable">可见性</param>publicvoidSetPropertyVisability(objectobj,stringpropertyName,boolvisable){Typetype=typeof(System.ComponentModel.BrowsableAttribute);PropertyDescriptorCollectionprops=TypeDescriptor.GetProperties(obj);AttributeCollectionattrs=props[propertyName].Attributes;FieldInfofld=type.GetField("browsable",BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.CreateInstance);fld.SetValue(attrs[type],visable);}}
界面代码publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}facea=newface();faceb=newface();privatevoidForm1_Load(objectsender,EventArgse){propertyGrid1.SelectedObject=a;propertyGrid2.SelectedObject=b;}privatevoidpropertyGrid1_PropertyValueChanged(objects,PropertyValueChangedEventArgse){propertyGrid1.SelectedObject=a;propertyGrid2.SelectedObject=b;}}
运行界面(初始默认为圆形)然后我讲左边PropertyGrid中的形状改为矩形,右边的与跟着变了。我希望右边的不要跟着变。求大神指点啊100分啊解决了再送100分
解决方案
解决方案二:
本身设计有问题,以后加个三角形怎么办,矩形为什么有半径?
解决方案三:
我觉得可以用嵌套类,根据类型实例化特定的类,不一致的不实例化它然后属性里用个泛型来引用这个类
解决方案四:
为什么不能System.Reflection.Emit命名空间的一些类,动态创建类及其拥有的属性.
解决方案五:
既然用到了TypeDescriptor,那就还是基于这个体系,继承一个TypeDescriptionProvider和CustomTypeDescriptor,用默认的作为parent,overrideGetProperties方法,里面根据需要过滤属性,使用TypeDescriptor.AddProvider对那个类型添加自己的这个provider就可以了。
解决方案六:
既然是面向对象编程,就要合理使用继承(也就是建不同的类),至于改动有多大,不懂真正的面向对象编程的人是不知道的.
解决方案七:
PropertyGrid本身就可以编码实现哪些显示,哪些不显示。——这个里面的PropertyGrid就是动态生成的。
解决方案八:
核心代码懒得找了。自己下载Demo看吧。上面的匹配引擎介绍:http://www.shuxiaolong.com/Project/0/5I7UFN38GEQ.aspx上面的匹配引擎下载:http://www.shuxiaolong.com/DoAjax/DownloadHandler.ashx?Number=5I7UG4TJGY4