在 运行 时间隐藏 PropertyGrid 中的一些属性

Hide some properties in PropertyGrid at run-time

我正在做一个允许用户自定义 Control 属性的项目。我有一个表单,其中包含 LabelTextBoxButtonPropertyGrid 控件。当用户单击 Label 时,我在 ProeprtyGrid 中显示 Label 的属性,使用以下代码一切正常:

propertyGrid1.SelectedObject = SelectedControl;

但我只想显示一些属性,例如 BackColorFontForeColorText。是否可以隐藏属性,因为我不希望用户更改它或向他们显示?如果是,如何?

更新

请注意这仅对隐藏属性有用(当您可以时)。 Reza Aghaei 答案实际上是正确答案。

我会把它留在这里,因为它适用于另一种情况,当您只是想在可以访问它时隐藏 属性。

原创

最简单的方法可能是使用

[Browsable(false)]

BrowsableAttribute Class

Specifies whether a property or event should be displayed in a Properties window.

[Browsable(false)]
public int SecretSquirrels
{
  get; set;
}

另外正如 Marc Gravell 所指出的,还有

PropertyGrid.BrowsableAttributes Property

Gets or sets the browsable attributes associated with the object that the property grid is attached to.

我相信您正在寻找自定义类型描述符。

虽然另一个答案是共享有关 Browsable 属性和 PropertyGridBrowsableAttributes 的正确信息,但我认为这不是解决问题的合适的实际解决方案。

设置 Browsable 属性或现有控件 class 的任何其他自定义属性(如 LabelButton 等)是不切实际的。因为在这种情况下,op 需要覆盖那些 classes 的所有属性,并用合适的属性装饰它们。更糟糕的是,并非所有属性都是可覆盖的。

什么是实际解决方案?

正如我之前提到的,我相信您正在寻找自定义类型描述符。您可以提供有关分配新 TypeDescriptor 或实现 ICustomTypeDescriptor 或派生自 CustomTypeDescriptor 的对象的元数据。

例子

例如,我创建了一个从 CustomTypeDescriptor 派生的 CustomObjectWrapper class,它在构造函数中接受一个对象。这样我就可以通过覆盖 GetProperties.

来简单地过滤包装对象的属性

然后我没有将 button1 分配给 PropertyGrid,而是将其包装在 CustomObjectWrapper 中并将 CustomObjectWrapper 分配给 属性 网格。这样它只显示过滤后的属性,属性实际上来自 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);

您只需将新的 属性 名称添加到 CustomObjectWrapperBrowsableProperties。这是一个 public 属性.