0

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

[过时(“用thingy代替获取其他东西”,true)]

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

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

4

1 回答 1

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

于 2012-07-02T10:40:09.503 回答