'.net Windows forms Property Grid

I have a .NET windows forms property grid which is tied to the collection of entities

public class Entity
{

public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}

It has a collectioneditor derived from CollectionEditor and attached to entities collection. The collection Editor works perfectly well when invoked from the property grid .

[Editor(typeof(EntityCollectionEditor), typeof(UITypeEditor))]
    public EntityCollection Entities
    {
        get { return entityCollection; }
    }

How can i invoke the propertygrid's instance Collection Editor on the click of a toolbar button ?

The propertygrid instance is EntityPropertyGrid.



Solution 1:[1]

How can i invoke the propertygrid's instance Collection Editor on the click of a toolbar button ?

By this, I assume you mean you want the PropertyGrid to give focus to the propert-grid row for your Entities property, which should activate or open the editor.

Surprisingly this is not trivial because PropertyGrid does not give you a straightforward way to enumerate all rows in the grid... or any of the grid-items except the currently selected row.

Fortunately you can do it by traversing the object-graph from SelectedGridItem:

Something like this:

using System.Linq;
using System.Windows.Forms;

// ...

void GiveFocusToEntitiesRow( PropertyGrid g )
{
    GridItem rootItem;
    {
        GridItem arbitrary = g.SelectedGridItem;
        while( arbitrary.Parent != null ) arbitrary.Parent;

        rootItem = arbitrary;
    }

    GridItem entitiesPropertyItem = EnumerateAllItems( rootItem )
        .First( item => item.PropertyDescriptor.Name == nameof(SomethingOrOther.Entities) );

    g.Focus();
    entitiesPropertyItem.Select();
    SendKeys.SendWait("{F4}"); // Enter edit mode
}

private static IEnumerable<GridItem> EnumerateAllItems( GridItem item )
{
    yield return item;
    
    foreach( GridItem child in item.GridItems )
    {
        foreach( GridItem grandChild in EnumerateAllItems( item: child ) )
        {
            yield return grandChild;
        }
    }
}

(I appreciate having two levels of foreach in EnumerateAllItems is a tad confusing, but it's an unfortunate a consequence of how C# lazy enumerators work).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dai