我相信你正在寻找自定义类型描述符。
虽然其他答案分享了关于PropertyGrid
的Browsable
属性和BrowsableAttributes
的正确信息,但我认为这不是解决问题的适当实际方法。
对于现有的控件类(如Label
、Button
等),设置Browsable
属性或任何其他自定义属性都不切实际。因为这样,操作者需要覆盖这些类的所有属性,并用适当的属性对其进行装饰。更糟糕的是,并非所有属性都可重写。
什么是切实可行的解决方案?
正如我之前提到的,我认为你正在寻找自定义类型描述符。您可以提供有关对象的元数据,分配新的TypeDescriptor
或实现ICustomTypeDescriptor
或从CustomTypeDescriptor
派生。
示例
例如,在此处,我创建了一个从CustomTypeDescriptor
派生的CustomObjectWrapper
类,该类在构造函数中接受一个对象。通过这种方式,我可以通过重写GetProperties
来简单地过滤包装对象的属性。
然后,我将其包装在CustomObjectWrapper
中,而不是将button1
分配给PropertyGrid
。通过这种方式,它只显示过滤后的属性,而这些属性实际上来自于button1
。
以下是实现:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
public class CustomObjectWrapper : CustomTypeDescriptor
{
public object WrappedObject { get; private set; }
public List<string> BrowsableProperties { get; private set; }
public CustomObjectWrapper(object o)
:base(TypeDescriptor.GetProvider(o).GetTypeDescriptor(o))
{
WrappedObject = o;
BrowsableProperties = new List<string>() { "Text", "BackColor" };
}
public override PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(new Attribute[] { });
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
.Where(p=>BrowsableProperties.Contains(p.Name))
.Select(p => TypeDescriptor.CreateProperty(
WrappedObject.GetType(),
p,
p.Attributes.Cast<Attribute>().ToArray()))
.ToArray();
return new PropertyDescriptorCollection(properties);
}
}
并且用法:
propertyGrid1.SelectedObject = new CustomObjectWrapper(button1)
您可以将新的属性名称简单地添加到
CustomObjectWrapper
的
BrowsableProperties
中。这是一个公共属性。
properties
参数是一个IDictionary<string, PropertyDescriptor>
。可以使用properties.Remove("[PropertyName]")
来删除属性。 - JimiControlDesigner
,就像这篇文章或这篇文章中所示。但是在这里,OP要求在运行时通过设置propertyGrid1.SelectedObject
来实现。这就是为什么我使用了TypeDescriptor
。 - Reza Aghaei