我必须关注问题,
在地图编辑器中,您可以在对象上放置“关节”(FarseerPhysics),有23种类型的关节(在枚举中)。关节几乎相同(每种关节类型只有1-2个新属性)。我想让用户使用WinForm PropertyGrid更改关节。 因此,如果用户更改属性“JointType”(枚举),PropertyGrid需要隐藏旧属性并显示新属性,有没有办法实现这一点? (所有关节的所有属性都保存在一个名为JointItem的类中,我只需要动态显示/隐藏其中一些)
答案 0 :(得分:3)
PropertyGrid
中没有简单易用的内置支持,可根据另一个属性的值动态更改哪些属性可见。这并不意味着它无法完成,只需要做一些工作。
正如您已经发现的那样,控制属性是否可见的是BrowsableAttribute
。所以基本上你需要动态更改这个属性,这样做的方法是为你的类创建自己的TypeProvider
和TypeDescriptor
,动态返回Browsable(false)
或{{1}根据类中另一个属性的值隐藏/显示属性的属性。我不会试图描述Browsable(true)
和TypeProvider
如何在这里工作,因为它是一个相当漫长的主题,并且已经有很多关于此主题的信息已经在网上提供。
此外,您需要在属性上指定TypeDescriptor
属性,以控制是否应显示其他属性。这将强制propertygrid在其值更改时重新查询属性列表的[RefreshProperties(RefreshProperties.All)]
,从而使TypeDescriptor
有机会返回不同的属性集,或者返回它返回的属性的不同属性。
我希望这至少能指出你正确的方向。不幸的是,将这些东西粘合在一起需要花费很多工作。
答案 1 :(得分:0)
这是一种用于更改JointItem类中的属性的Browsable属性的方法:
private void ChangeBrowsability(object pThis, string pProperty, bool pBrowsable)
{
PropertyDescriptor pdDescriptor = TypeDescriptor.GetProperties(pThis.GetType())[pProperty];
BrowsableAttribute baAttribute = (BrowsableAttribute)pdDescriptor.Attributes[typeof(BrowsableAttribute)];
FieldInfo fiBrowsable = baAttribute.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
fiBrowsable.SetValue(baAttribute, pBrowsable);
}
然后,如果没有其他序列或类似内容,您可能会很长:
JointItem jiThis = WhereEverYouGetYourJointItemFrom();
if (jiThis.JointType == eJoinType.Elbow)
{
ChangeBrowsability(jiThis, "JointAngle", true);
ChangeBrowsability(jiThis, "MinAngle", true);
ChangeBrowsability(jiThis, "MaxAngle", true);
ChangeBrowsability(jiThis, "ScrewType", false);
//...
}
else ...
您当然需要“使用”剂量!
using System.ComponentModel;
using System.Reflection;