控件中属性的显示与否可以通过Browsable属性设置。可以通过将可写性设为false使属性变灰病不可更改。属性的动态隐藏,最理想状态是动态修改Browsable属性,以实现。然而属性(property)的各项属性(attribute)无法动态修改。运行时即为只读。解决思路仿照本地化,虽然不能将参数进行转换(因为参数为bool类型,且值固定),但是可以通过某种方法将传入空间的属性值动态修改。按此思路,首先使用[TypeConverter(typeof(myTypeConverter))加入自定义属性转换器重写其GetProperties方法,设定临时变量对应需动态修改的属性值,并将其作为返回该属性值时的返回值。之后,需要控件重新选定对象(设定propertyGrid.selectedObject)以更改显示画面。具体代码如下:
class Class2TypeConverter:ExpandableObjectConverter
{
...
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection preDC = TypeDescriptor.GetProperties(value);
TClass2 temp = (TClass2)value;
PropertyDescriptorCollection result = new PropertyDescriptorCollection(null);
foreach (PropertyDescriptor pd in preDC)
{
if (pd.Name == "A"||pd.Name =="B")//选定所需动态表示属性
{
TestPropertyDescriptor tpd = new TestPropertyDescriptor(pd, temp.v);//生成替代属性描述
result.Add(tpd);
}
else
{
result.Add(pd);
}
}
return result;//base.GetProperties(context, value, attributes);
}
}
class TestPropertyDescriptor : PropertyDescriptor//替代原有属性描述的类:继承属性描述类
{
private PropertyDescriptor basePropertyDescriptor;
private bool rOnly;//设置对应属性(对应前文临时变量)
public TestPropertyDescriptor(PropertyDescriptor basePropertyDescriptor, bool readOnly): base(basePropertyDescriptor)//构造函数,由readOnly参数确定属性的可写性。
{
this.basePropertyDescriptor = basePropertyDescriptor;
rOnly = readOnly;
}
public override bool CanResetValue(object component)
{
return basePropertyDescriptor.CanResetValue(component);
}
...
//This property is the key point;更改可写性属性的返回值,属性本身的可写性并不改变。只是`````//让控件以为产生了改变
public override bool IsReadOnly
{
get
{
return rOnly;
}
}
//完美状态下应该修改Browsable属性,但是笔者测试发现修改后控件并不承认,由于不了``````//解控件是否从别的调用获得了属性原有的Browsable值,遂放弃。
public override bool IsBrowsable
{
get
{
return basePropertyDescriptor.IsBrowsable;
}
}
...
}
注:1、属性值改变后切记重新设定控件选定的当前对象。
2、2008、7、21日今天在寻找给分类后的属性排序的方法时看到一段代码,恍然大悟。之所以browsable修改后属性无法动态隐藏是因为propertygrid是根据propertyDescritor决定什么属性显示什么属性不显示,也就是说,propertyDescritorCollection中存在的属性描述对象都会被表现,而不管他的IsBrowsable是否为true。要想使某一属性无法显示,直接将其属性描述从propertyDescritorCollection中移出即可。(具体实现可参见后续章节有关属性排序的部分)
本文介绍了如何在propertyGrid控件中实现属性的动态隐藏和不可更改。通过自定义TypeConverter并重写GetProperties方法,创建替代属性描述,以达到控制属性显示和可编辑性的目的。关键在于更新控件选定的对象以反映属性状态的变更。注意,即使修改了Browsable属性,propertyGrid仍可能不会响应,因此需要从PropertyDescriptorCollection中移除属性描述来真正隐藏属性。

2万+

被折叠的 条评论
为什么被折叠?



