【问题标题】:Make all properties with specific Category name invisible in PropertyGrid in c# Winforms at Runtime based on some condition根据某些条件,在运行时 c# Winforms 中的 PropertyGrid 中使具有特定类别名称的所有属性不可见
【发布时间】:2017-03-14 12:13:49
【问题描述】:

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

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

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

新增代码:

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

为什么它不起作用?

因为Browsable属性只能接受Constant。而matchSomeRunTimeCondition 不是一个常数。用户可以在应用程序仍在运行时随时更改它。

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

如果(属性类别 == “额外”){

//不在propertygrid中显示该属性。

//或者换句话说,在运行时将 Browasable Attribute 设为 False。

}

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

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

但我需要帮助来实现这一点。

注意:我愿意在编译时将可浏览属性设置为 true / false。但是我想要一种机制来在我的应用程序运行时设置它,请在执行此操作时提供帮助。

寻找代码解决方案。

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

  • Visual Studio 2010
  • .Net 3.5
  • Windows 10 操作系统(是的,我知道)

【问题讨论】:

  • 您考虑过adding attribute to a property during runtime 吗?所以想法是使用反射,检查Category 属性值并将适当的Browsable 属性添加到属性中。
  • 我对 Reflection 很陌生,需要一些时间来尝试解决我的问题,请提前原谅我。如果您能向我展示我可以以适合问题条件的方式使用的代码中最重要的部分(不强制),我将不胜感激。
  • 不可能如here所述
  • @TnTinMn,谢谢。在我的代码中,当我使用此解决方案时出现 nullValue 异常,在调试时我发现变量 theDescriptor 在声明时为空。我也知道如何改变它会导致 propertyGrid 发生变化,但看起来向前迈出了一大步。

标签: c# winforms propertygrid


【解决方案1】:

使用 TnTinMn 发布的答案,我修改了我的代码,使其在运行时隐藏所有选择性属性。

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 的精彩帖子 (Conditional "Browsable" Attribute),我从中得出了最终解决方案。

【讨论】:

    【解决方案2】:

    这对我有用

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2013-06-26
      • 2018-02-26
      相关资源
      最近更新 更多