ExpandableObjectConverter as a GridItem - How to initialize inner GridItem to be expanded while outer one is collapsed?

StackOverflow https://stackoverflow.com/questions/20351606

Question

I have a PropertyGrid populated with an expandable property, called Outer (among many others).
Class Outer contains another expandable property, called Inner.
I'm trying to initialize my form so that Inner is expanded and Outer is collapsed, so that when the form is loaded, I get:

  • Outer is collapsed at init, so its properties do not "pollute" the view.
  • Clicking to expand Outer will show Inner already expanded.

I do NOT wish to completely override the expanding of Outer to automatically expand Inner, but only to set the initial state as described.

  1. Setting GridItem.Expanded to true for both Outer and Inner, works: In this case, after the form is loaded, clicking to collapse Outer will not affect the Expanded status of Inner, so it can remain expanded even when not visible.
  2. Setting only that of Inner to true, seems to have no effect at all.
  3. Setting both to true, then setting that of Outer to false, is exactly the same as #2, only quite silly.

This is how I've implemented option #3, as seen on answers to similar questions:

// Suppose I have a reference to the root, in pgRoot
for (int i = 0; i < pgRoot.GridItems.Count; i++)
{
    if (pgRoot.GridItems[i].Label == "Outer Display Name")
    {
        GridItem giOuter = pgRoot.GridItems[i];
        giOuter.Expanded = true;

        for (int j = 0; j < options.GridItems.Count; j++)
        {
            if (giOuter.GridItems[j].Label == "Inner Display Name")
            {
                GridItem giInner = giOuter.GridItems[j];
                giInner.Expanded = true;
                giOuter.Expanded = false;
                break;
            }
        }
        break;
    }
}

I don't understand why setting giOuter.Expanded = false causes the form to load with Inner collapsed, whereas scenario #1 above allows - after the form is loaded - to collapse Outer (via the GUI) without messing with Inner's state.

Was it helpful?

Solution

Call the ExpandAllInnerItems method in your Form.Load event handler. It works as you expected. But if you put in your form initialization then it won't work as the default expansion logic of PropertyGrid kicks in during Load and overrides the custom expansion logic.

private void ExpandAllInnerItems()
{
    GridItem root = Root;
    IList<GridItem> allItems = GetAllChildGridItems(root);
    foreach (GridItem item in allItems)
    {
        if (item.Parent != root && item.Expandable)
        {
            item.Expanded = true;
        }
        else if(item.GridItemType == GridItemType.Category)
        {
            item.Expanded = false;
        }
    }
}

private GridItem Root
{
    get
    {
        GridItem aRoot = propertyGrid1.SelectedGridItem;
        do
        {
            aRoot = aRoot.Parent ?? aRoot;
        } while (aRoot.Parent != null);
        return aRoot;
    }
}

private IList<GridItem> GetAllChildGridItems(GridItem theParent)
{
    List<GridItem> aGridItems = new List<GridItem>();
    foreach (GridItem aItem in theParent.GridItems)
    {
        aGridItems.Add(aItem);
        if (aItem.GridItems.Count > 0)
        {
            aGridItems.AddRange(GetAllChildGridItems(aItem));
        }
    }
    return aGridItems;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top