【问题标题】:Hide some properties in PropertyGrid at run-time在运行时隐藏 PropertyGrid 中的一些属性
【发布时间】:2019-01-07 18:15:45
【问题描述】:

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

propertyGrid1.SelectedObject = SelectedControl;

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

【问题讨论】:

    标签: c# .net winforms propertygrid


    【解决方案1】:

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

    虽然另一个答案是分享有关Browsable 属性和BrowsableAttributes 的正确信息PropertyGrid,但我想说这不是解决该问题的适当实用解决方案。

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

    什么是切实可行的解决方案?

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

    示例

    例如,我创建了一个从CustomTypeDescriptor 派生的CustomObjectWrapper 类,它在构造函数中接受一个对象。这样我就可以通过覆盖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。这是公共财产。

    【讨论】:

    • 您对拥有一个继承ControlDesigner 并覆盖其PreFilterProperties 的Designer 类有何看法? properties 参数是 IDictionary&lt;string, PropertyDescriptor&gt;。然后可以使用properties.Remove("[PropertyName]") 删除属性。
    • 我试过这个,效果很好。非常感谢。
    • @Jimi 感谢您的反馈。如果要求是设计时,我会使用ControlDesigner,如this postthis one。但是在这里,OP 通过设置propertyGrid1.SelectedObject 来询问它的运行时间。这就是我使用TypeDescriptor的原因。
    • 是的,当然。我对您对此事的看法更感兴趣(最终的问题,缺点......)。顺便说一句,这些答案并没有出现在搜索中。真可惜。
    【解决方案2】:

    更新

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

    我将把它留在这里,因为它适用于其他情况,当您只是想在可以访问某个属性时隐藏它。

    原创

    最简单的方法可能是使用

    [Browsable(false)]
    

    BrowsableAttribute Class

    指定属性或事件是否应显示在 属性窗口。

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

    正如Marc Gravell所指出的,还有

    PropertyGrid.BrowsableAttributes Property

    获取或设置与该对象关联的可浏览属性 属性网格已附加到。

    【讨论】:

    • 概括一下,有一个BrowsableAttributes 属性可用于提供自定义过滤器(或:同一对象上的不同视图),但是:很有可能 i> [Browsable(false)] 可以满足 OP 的所有需求
    • 谢谢。我需要创建自定义PropertyGrid 吗?假设我要显示此列表string[] ShowThisPropertyList = new string[] { "Text", "BackColor", "ForeColor" };
    • @Zhyke 你可能不得不创建一个新对象来引用你想要的标签中的属性,这就是你放在 propertyGrid 中的那个
    • 虽然这个答案是共享有关Browsable 属性和PropertyGridBrowsableAttributes 的正确信息,但我会说这不是解决该问题的适当实际解决方案。为现有控件类(如LabelButton 等)设置Browsable 属性或任何其他自定义属性是不切实际的。因为这样的话,op需要覆盖那些类的所有属性,并用合适的属性来装饰它们。更糟糕的是,并非所有属性都是可覆盖的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 2013-09-26
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多