I have to following problem,
In a map-editor you can place \"Joints\" (FarseerPhysics) on objects, there are 23 types of joints (in an enum). The joints are all pretty m
There is no simple to use built-in support in PropertyGrid
for dynamically altering which properties are visible depending on the value of another property. This doesn't mean it can't be done, just that it takes a bit of work.
As you've already discovered, what controls whether a property is visible or not is the BrowsableAttribute
. So basically you need to change this attribute dynamically, and the way to do that is to create your own TypeProvider
and TypeDescriptor
for your class, that dynamically returns the Browsable(false)
or Browsable(true)
attribute for the property to be hidden/shown depending on the value of another property in the class. I will not attempt to describe how TypeProvider
and TypeDescriptor
works here, since it is quite a lengthy subject and there is much information readily available on this subject on the web already.
In addition you need to specify the [RefreshProperties(RefreshProperties.All)]
attribute on the property controlling whether another property should be visible or not. This will force the propertygrid to requery the TypeDescriptor
for the list of properties whenever its value is changed, giving your TypeDescriptor
the chance to return a different set of properties, or different attributes on the properties it returns.
I hope this at least points you in the right direction. Unfortunately it takes a quite bit of work to glue these things together.
Here is a method for changing the Browsable attribute of a property in your JointItem class:
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);
}
Then you could have a big long if then else sequence or the likes:
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 ...
Of course you need your dose of "using"s!
using System.ComponentModel;
using System.Reflection;