简体   繁体   English

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

[英]Hide some properties in PropertyGrid at run-time

I am doing a project that allows user to customized the properties of a Control .我正在做一个项目,允许用户自定义Control的属性。 I have a form that has a control like Label , TextBox , Button and PropertyGrid control.我有一个表单,它有一个控件,如LabelTextBoxButtonPropertyGrid控件。 When the user clicks on the Label i am showing the properties of the Label in the ProeprtyGrid which is all working fine using below code:当在用户点击Label我显示的的属性LabelProeprtyGrid这是使用以下代码中的所有工作罚款:

propertyGrid1.SelectedObject = SelectedControl;

But I just want to show some properties like BackColor , Font , ForeColor , Text .但我只想显示一些属性,如BackColorFontForeColorText Is it possible to hide the properties since I don't want user to change it or show to them?是否可以隐藏属性,因为我不希望用户更改它或向他们显示? If yes, how?如果是,如何?

I believe you are looking for custom type descriptors.我相信您正在寻找自定义类型描述符。

While the other answer is sharing correct information about Browsable attribute and BrowsableAttributes of PropertyGrid , but I'd say it's not a proper practical solution for the problem.虽然另一个答案是共享有关PropertyGrid Browsable属性和BrowsableAttributes的正确信息,但我认为这不是该问题的正确实用解决方案。

It's not practical to set Browsable attribute, or any other custom attributes for existing control classes like Label , Button , and so on.为现有控件类(如LabelButton等)设置Browsable属性或任何其他自定义属性是不切实际的。 Because in this way, the op needs to override all properties of those classes and decorate them with suitable attribute.因为通过这种方式,op 需要覆盖这些类的所有属性并用合适的属性装饰它们。 And even worst, not all propertied are overridable.甚至最糟糕的是,并非所有的财产都是可覆盖的。

What's the practical solution?实际的解决方案是什么?

As I mentioned earlier, I believe you are looking for custom type descriptors.正如我之前提到的,我相信您正在寻找自定义类型描述符。 You can provide metadata about an object assigning a new TypeDescriptor or implementing ICustomTypeDescriptor or deriving from CustomTypeDescriptor .您可以提供有关分配新TypeDescriptor或实现ICustomTypeDescriptor或从CustomTypeDescriptor派生的对象的元数据。

Example例子

Here for example, I create a CustomObjectWrapper class deriving from CustomTypeDescriptor which accepts an object in constructor.例如,我在这里创建了一个从CustomTypeDescriptor派生的CustomObjectWrapper类, CustomTypeDescriptor在构造函数中接受一个对象。 This way I can simply filter the properties of the wrapped object by overriding GetProperties .通过这种方式,我可以通过覆盖GetProperties来简单地过滤包装对象的属性。

Then instead of assigning button1 to PropertyGrid , I wrap it in CustomObjectWrapper and assing the CustomObjectWrapper to property grid.然后我没有将button1分配给PropertyGrid ,而是将它包装在CustomObjectWrapper并将CustomObjectWrapper给属性网格。 This way it just shows the filtered properties and the properties are actually come from button1 .这样它只显示过滤后的属性,而这些属性实际上来自button1

Here is the implantation:这是植入:

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);
    }
}

And as usage:并作为用法:

propertyGrid1.SelectedObject = new CustomObjectWrapper(button1);

You can simply add new property names to BrowsableProperties of the CustomObjectWrapper .您可以简单地添加新的属性名BrowsableProperties的的CustomObjectWrapper It's a public property.这是公共财产。

UPDATE更新

Please note this is only useful for Hiding properties (when you can).请注意,这仅对隐藏属性有用(如果可以)。 Reza Aghaei answer is actually the correct answer. Reza Aghaei 的答案实际上是正确的答案。

I'll leave this here as it's suitable for the other case when you just simply want to hide a property when you have access to it.我将把它留在这里,因为它适用于另一种情况,当您只想在可以访问属性时隐藏它。

Original原来的

Easiest way is probably to use最简单的方法可能是使用

[Browsable(false)]

BrowsableAttribute Class 可浏览属性类

Specifies whether a property or event should be displayed in a Properties window.指定是否应在“属性”窗口中显示属性或事件。

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

Also as pointed out by Marc Gravell , there is also也正如Marc Gravell所指出的,还有

PropertyGrid.BrowsableAttributes Property PropertyGrid.BrowsableAttributes 属性

Gets or sets the browsable attributes associated with the object that the property grid is attached to.获取或设置与属性网格附加到的对象关联的可浏览属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM