Question

Say we have a simple class model with classes as feilds (inside compiled, not modifiable Dll):

public class SubSubClassTest {
    public int Data { get; set; }
}

public class SubClassTest {
    public string InnerStr { get; set; }
    public int InnerInteger { get; set; }
    public SubSubClassTest InnerLoad { get; set; }

    public SubClassTest() {
        InnerLoad = new SubSubClassTest();
    }
}

public class Test {
    public string Str { get; set; }
    public int Integer { get; set; }

    public SubClassTest Load { get; set; }

    public Test() {
        Load = new SubClassTest();
    }
}

And we want to edit it using PropertyGrid.

public partial class ApplicationForm : Form {
    public ApplicationForm() {
        InitializeComponent();
        var test = new Test();
        propertyGrid.SelectedObject = test;
    }
}

And I do not have abilety to change classes (as I get them from Dll) and they have no [TypeConverter(typeof(ExpandableObjectConverter))] attribute on all members that are classes I get sush picture:

enter image description here

And members that are from my namespace class type are not editable.

If all such members havd [TypeConverter(typeof(ExpandableObjectConverter))] attribute I would have another picture and all would be fine:

enter image description here

I wonder how to make PropertyGrid use PropertyGrid for all nested classes?

No correct solution

OTHER TIPS

You could try changing the TypeConverterAttribute value using PropertyDescriptor and Reflection. I wouldn't recommend to do this but to show that its possible I have added the sample code. I verified with your example and it works. But I cannot assure that it would work in all scenarios. Food for thought...

var test = new Test();
SetTypeConverterAttribute(test);
propertyGrid.SelectedObject = test;

private void SetTypeConverterAttribute(Test test)
    {
        foreach (PropertyDescriptor item in TypeDescriptor.GetProperties(test))
        {
            TypeConverterAttribute attribute = item.Attributes[typeof(TypeConverterAttribute)] as TypeConverterAttribute;
            if (attribute != null && item.PropertyType == typeof(SubClassTest))
            {
                FieldInfo field = attribute.GetType().GetField("typeName", BindingFlags.NonPublic | BindingFlags.Instance);
                if (field != null)
                {
                    field.SetValue(attribute, typeof(ExpandableObjectConverter).FullName);
                }
            }
        }            
    }

If you have control over the classes, you can create a common base class and decorate this base class with the TypeConverterAttribute. In that case, any property that will reference any instance of this type will use the ExpandableObjectConverter, unless this behavior is overridden by the property (using another TypeConverterAttribute).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top