Search code examples
c#.netwinformspropertygridtypeconverter

Auto expand Property when changed PropertyGrid.PropertyValueChanged not works. (ExpandableObjectConverter classes)


I need to expand a PropertyGrid SelectedItem at design-time when I choose a property value. I try create CollectionEditor descendant which access the property grid. and do following in overridden CreateCollectionForm()

    protected override CollectionForm CreateCollectionForm()
    {
        var collectionForm = base.CreateCollectionForm();
        collectionForm.Shown += (s, e) =>
        {
            var propertyGrid = collectionForm.Controls[0].Controls.OfType<PropertyGrid>().First();   

            propertyGrid.PropertyValueChanged += (ss, ee) =>
            {
                if (ee.ChangedItem.Expandable)
                    ee.ChangedItem.Expanded = true;  // NOT WORKING.
            };
        };
        return collectionForm;
    }

Another guys asking something similar but not answered yet from long time ago. In my case I need expand selectedItem in winForms designer propertygrid. Automatically expand some properties in PropertyGrid

I see he try cast context as GridItem. Which in my side crash visual studio.

Anyhelp will be appreciated.


Solution

  • To do that a CollectionEditor descendant is must provided as follows:

    public class AdvancedCollectionEditor : System.ComponentModel.Design.CollectionEditor
    {       
        protected internal string formCaption;
        protected internal List<Type> excludedTypes = new List<Type>();
        protected internal bool allowMultiSelect;
        
        public AdvancedCollectionEditor(Type type) : base(type)
        {
            allowMultiSelect = true;
        }
    
        protected override Type[] CreateNewItemTypes()
        {
            if (CollectionItemType.IsAbstract)
            {
                List<Type> validTypes = new List<Type>();
                var types = Assembly.GetAssembly(CollectionItemType).GetTypes();
                foreach (var type in types)
                {
                    if (!type.IsAbstract && type.IsSubclassOf(CollectionItemType))
                    {
                        if (!excludedTypes.Contains(type))
                            validTypes.Add(type);
                    }
                }
                return validTypes.ToArray();
            }
            return base.CreateNewItemTypes();
        }
    
        protected override CollectionForm CreateCollectionForm()
        {
            var collectionForm = base.CreateCollectionForm();
            if (!string.IsNullOrWhiteSpace(formCaption))
                collectionForm.Text = formCaption;
            collectionForm.Size = new Size(640, 500);
            collectionForm.Shown += (s, e) =>
            {
                var propertyGrid = collectionForm.Controls[0].Controls.OfType<PropertyGrid>().First();
                propertyGrid.HelpVisible = true;
    
                propertyGrid.PropertyValueChanged += (ss, ee) =>
                {
                   // Note that ee.ChangedItem will never works
                    void ExpandChildGridItems(GridItem parent)
                    {
                        if (parent.Expandable)
                            parent.Expanded = true;
                        if (parent.GridItems.Count > 0)
                        {
                            foreach (GridItem child in parent.GridItems)
                                ExpandChildGridItems(child);
                        }
                    }
    
                    if (propertyGrid.SelectedGridItem.Expandable)
                        propertyGrid.SelectedGridItem.Expanded = true;
                    ExpandChildGridItems(propertyGrid.SelectedGridItem);
                };
            };
            return collectionForm;
        }
        protected override bool CanSelectMultipleInstances() => allowMultiSelect;
    }