我将属性Grid绑定到一堆由其他开发人员编写的自定义对象。这些对象不断被更改和更新,因此它们包含仅抛出 NotImplemented Exceptions 的属性。有时他们包括
等属性[已废弃(“使用thingy而不是获取其他东西”,true)]
而不是讨厌其他开发者。我知道的事情将在以后改变。我该怎么做才能确保我的属性Grid不会破坏这些特定的属性?
感谢您的帮助。其他开发者都很感激;)
答案 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将始终为空。