防止propertyGrid绑定到某些属性

时间:2012-07-02 06:02:03

标签: c# propertygrid obsolete

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

等属性
  

[已废弃(“使用thingy而不是获取其他东西”,true)]

而不是讨厌其他开发者。我知道的事情将在以后改变。我该怎么做才能确保我的属性Grid不会破坏这些特定的属性?

感谢您的帮助。其他开发者都很感激;)

1 个答案:

答案 0 :(得分:1)

我想你试图在运行时将PropertyGrid绑定到对象,而不是在设计器中。如果你的意思是winform设计器中的propertygrid,答案会有所不同,你应该看一下ControlDesigner的postFilterEvents方法。

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

    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将始终为空。