根据某些条件,使所有具有特定类别名称的属性在运行时的 c# Winforms 中的 PropertyGrid 中不可见

Make all properties with specific Category name invisible in PropertyGrid in c# Winforms at Runtime based on some condition

我的应用程序中有一个 属性 网格,它在 运行 时间显示所选控件的属性。

最近需要向现有控件添加一些额外的属性。为了适应这一点,引入了一个新类别,在该类别下添加了较新的属性。

现在我正在寻找一种机制来根据应用程序中的 运行 时间条件在 运行 时间隐藏这些新添加的属性。但是我对此没有合适的解决方案。

新增代码:

    [ReadOnly(true)]
    [Browsable(true)]
    [Category("Extra")]
    public int? FormID { get; set; }

    [Browsable(true)]
    [Category("Extra")]
    public int? jrxml_Id { get; set; }

我期望的工作:

    [ReadOnly(true)]
    [Browsable(matchSomeRunTimeCondition)]
    [Category("Extra")]
    public int? FormID { get; set; }

    [Browsable(matchSomeRunTimeCondition)]
    [Category("Extra")]
    public int? jrxml_Id { get; set; }

为什么不起作用?

因为BrowsableAttribute只能接受Constant。 matchSomeRunTimeCondition 不是常数。用户可以在应用程序仍在 运行ning 时随时更改它。

在代码中,如果有一个函数可以让我在 运行 时使这些不可见,如果有人能帮我写一个这样的函数或条件语句,我将非常感激:

If (property’s category == “Extra”) {

//Do not show this property in the propertygrid.

//Or in other words, make Browasable Attribute False at run time.

}

我的应用程序中的不同控件具有需要在 运行 时间隐藏的不同属性。

我有一个所有属性的列表,我想将这些属性隐藏在应用程序中选择的每个对象中,以显示在 属性 网格中。

但我需要有关如何实现此目标的帮助。

注意:我愿意在编译时将可浏览 属性 设置为 true / false。但是我想要一种机制在我的应用程序中将其设置为 运行 时间,请在这方面需要帮助。

正在寻找代码解决方案。

我的编码环境(由于公司遗留支持而无法更改):

使用 TnTinMn post 的回答,我修改了我的代码如下,使其在 运行 时间隐藏所有选择性属性。

private void ChangeVisibilityBasedOnMode( ref object[] v) {
    if (matchSomeRunTimeCondition) {
        List<string> PropertiesToHide = new List<string> {
            "FormID",
            "jrxml_Id",
        };
        foreach (var vObject in v) {
            var properties = GetProperties(vObject);
            foreach (var p in properties) {
                foreach (string hideProperty in PropertiesToHide ) {
                    if (p.Name.ToLower() == hideProperty.ToLower()) {
                        setBrowsableProperty(hideProperty, false, vObject);
                    }
                }
            }
        }
    }
}
private void setBrowsableProperty(string strPropertyName, bool bIsBrowsable, object vObject) {
    try {
        PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(vObject.GetType())[strPropertyName];
        BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)];
        FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance);
        isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable);
    } catch (Exception) { }
}

也感谢 neoikon 的精彩 post (Conditional "Browsable" Attribute),我从中得到了最终的解决方案。

这就是我的工作方式

    private void SetVisibleSearchOptions(Type searchType, bool visible)
    {
        try
        {
            TypeDescriptor.AddAttributes(searchType, new BrowsableAttribute(visible));
        }
        catch (Exception ex)
        {

        }
    }