Sam*_*meh 1 .net c# vb.net user-controls winforms
我在.NET中有一个用户控件,有2个新属性
Prop1: Boolean
Prop2: String
Run Code Online (Sandbox Code Playgroud)
当用户将Prop1设置为false时,我想在属性网格中创建Prop2 READONLY.
如果要根据某些条件在运行时使属性外观为只读(灰色),则需要CustomTypeDescriptor为您的类分配一个类,该类提供有关属性网格的类的元数据.
PropertyGridcontrol使用对象的类型描述符来提取有关其要显示的属性的信息.类型描述符返回PropertyDescriptor对象列表作为属性列表.每个PropertyDescriptor包含一些方法和属性,以返回显示名称,描述和有关该属性的其他信息.如果财产应该是只读IsReadOnly的,PropertyDescriptor则负责通知PropertyGrid财产.
例
在以下示例中,我创建了一个包含两个属性的类.Editable和StringProperty.如果Editable是,true那么它StringProperty是可编辑的,否则它将是只读的,并将显示为灰色PropertyGrid.
MyPropertyDescriptor
它负责提供财产的元数据.在实现这个类时,对于大多数属性,我们将使用使用原始属性的实现的简单实现,但是IsReadOnly我们将根据Editable所有者对象的属性值来决定:
using System;
using System.ComponentModel;
using System.Linq;
public class MyPropertyDescriptor : PropertyDescriptor
{
PropertyDescriptor p;
SampleClass o;
public MyPropertyDescriptor(PropertyDescriptor originalProperty, SampleClass owenr)
: base(originalProperty) { p = originalProperty; o = owenr; }
public override bool CanResetValue(object component)
{ return p.CanResetValue(component); }
public override object GetValue(object component) { return p.GetValue(component); }
public override void ResetValue(object component) { p.ResetValue(component); }
public override void SetValue(object component, object value)
{ p.SetValue(component, value); }
public override bool ShouldSerializeValue(object component)
{ return p.ShouldSerializeValue(component); }
public override AttributeCollection Attributes { get { return p.Attributes; } }
public override Type ComponentType { get { return p.ComponentType; } }
public override bool IsReadOnly { get { return !o.Editable; } }
public override Type PropertyType { get { return p.PropertyType; } }
}
Run Code Online (Sandbox Code Playgroud)
MyTypeDescriptor
它负责提供对象的属性列表.对于StringProperty这些我们将在运行时改变其行为,我们将返回MyPropertyDescriptor:
using System;
using System.ComponentModel;
using System.Linq;
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor d;
SampleClass o;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor, SampleClass owner)
: base(originalDescriptor) { d = originalDescriptor; o = owner; }
public override PropertyDescriptorCollection GetProperties()
{ return this.GetProperties(new Attribute[] { }); }
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Select(p => p.Name == "StringProperty" ? new MyPropertyDescriptor(p, o) : p)
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
Run Code Online (Sandbox Code Playgroud)
MyTypeDescriptionProvider
当某人(如属性网格)请求类型描述时,它负责返回对象的类型描述符:
using System;
using System.ComponentModel;
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type type, object o)
{
ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(type, o);
return new MyTypeDescriptor(baseDescriptor, (SampleClass)o);
}
}
Run Code Online (Sandbox Code Playgroud)
SampleClass
最后,该类的实现:
using System;
using System.ComponentModel;
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class SampleClass
{
[RefreshProperties(RefreshProperties.All)]
public bool Editable { get; set; }
string sp;
public string StringProperty
{
get { return sp; }
set
{
if (Editable)
sp = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果
进一步阅读
您可以在以下帖子中阅读其他一些解决方案: