【问题标题】:Preventing a propertyGrid from binding to certain properties防止 propertyGrid 绑定到某些属性
【发布时间】:2012-07-02 06:02:02
【问题描述】:

我将属性 Grid 绑定到一堆由其他开发人员编写的自定义对象。这些对象不断地被更改和更新,因此它们包含只会抛出 NotImplemented Exceptions 的属性。有时它们包括像

这样的属性

[Obsolete("用 thingy 代替得到其他东西", true)]

而不是惹恼其他开发人员。我知道以后会改变的事情。我可以做些什么来确保我的属性网格不会在这些特定属性上中断?

感谢您的帮助。其他开发人员对此表示赞赏;)

【问题讨论】:

    标签: c# propertygrid obsolete


    【解决方案1】:

    我想您正在尝试在运行时将 PropertyGrid 绑定到对象,而不是在设计器中。如果你指的是winform设计器中的propertygrid,答案会不一样,你应该看看ControlDesigner的postFilterEvents方法。

    最简单的解决方案是将要隐藏的属性的 BrowsableAttribute 设置为 false。这意味着当其他开发人员添加 ObsoleteAttribute 时,他们也应该添加 [Browsable(false)]。但我知道您想要更“自动”的东西。您可以编写一个方法来更改对象属性的可浏览属性,然后再将其传递给 PropertyGrid。这可以通过获取每个属性的 TypeDescriptor,然后获取其 BrowsableAttribute,并根据存在 ObsoleteAttribute 或抛出异常的事实来设置其值(这必须通过反射来完成,因为 browsable 是私有的) .代码可能是这样的:

        private static void FilterProperties(object objToEdit)
        {
            Type t = objToEdit.GetType();
            PropertyInfo[] props = t.GetProperties();
            // create fooObj in order to have another instance to test for NotImplemented exceptions 
            // (I do not know whether your getters could have side effects that you prefer to avoid)
            object fooObj = Activator.CreateInstance(t);
            foreach (PropertyInfo pi in props)
            {
                bool filter = false;
                object[] atts = pi.GetCustomAttributes(typeof(ObsoleteAttribute), true);
                if (atts.Length > 0)
                    filter = true;
                else
                {
                    try
                    {
                        object tmp = pi.GetValue(fooObj, null);
                    }
                    catch
                    {
                        filter = true;
                    }
                }
                PropertyDescriptor pd = TypeDescriptor.GetProperties(t)[pi.Name];
                BrowsableAttribute bAtt = (BrowsableAttribute)pd.Attributes[typeof(BrowsableAttribute)];
                FieldInfo fi = bAtt.GetType().GetField("browsable",
                                   System.Reflection.BindingFlags.NonPublic |
                                   System.Reflection.BindingFlags.Instance);
                fi.SetValue(bAtt, !filter);
            }
        }
    

    这应该可行,但它有一个限制。您正在编辑的类中必须至少有一个 BrowsableAttribute(设置为 true 或 false 都没有关系),否则 PropertyGrid 将始终为空。

    【讨论】:

      猜你喜欢
      • 2011-02-25
      • 2012-12-28
      • 1970-01-01
      • 2018-04-12
      • 2021-10-03
      • 2021-01-23
      • 2010-10-28
      • 1970-01-01
      • 2020-04-01
      相关资源
      最近更新 更多