How to enumerate PropertyGrid items?
Asked Answered
A

3

9

I have a PropertyGrid with assigned to it some object.

var prpGrid = new PropertyGrid();
prp.SelectedObject = myObject;

I want to get all grid items like I can get selectedGridItem property:

var selectedProperty = prpGrid.SelectedGridItem;

Can I do this?

Anlage answered 2/3, 2011 at 14:49 Comment(1)
Surprisingly, this appears to be totally impossible.Brigandine
B
6

Here is a piece of code that will retrieve all GridItem objects of a property grid:

public static GridItemCollection GetAllGridEntries(this PropertyGrid grid)
{
    if (grid == null)
        throw new ArgumentNullException("grid");

    var field = grid.GetType().GetField("gridView", BindingFlags.NonPublic | BindingFlags.Instance);
    if (field == null)
    {
        field = grid.GetType().GetField("_gridView", BindingFlags.NonPublic | BindingFlags.Instance);
        if (field == null)
            return null;
    }

    var view = field.GetValue(grid);
    if (view == null)
        return null;

    try
    {
        return (GridItemCollection)view.GetType().InvokeMember("GetAllGridEntries", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, view, null);
    }
    catch
    {
        return null;
    }
}

Of course, since this is using an undocumented private field of the Property Grid, is not guaranteed to work in the future :-)

Once you have all the GridItems, you can filter them using the GridItem.GridItemType property.

Bivalve answered 3/3, 2011 at 13:37 Comment(0)
C
2

If you only need the object's properties, you can get those via Reflection:

PropertyDescriptorCollection myObjectProperties = TypeDescriptor.GetProperties(myObject);

If you did hide some of the properties with BrowsableAttribute(false), you can use GetProperties(Type, Attribute[]) to filter those out.

I am not aware of a method that returns a GridItem collection.

Update
Of course you can also obtain the string that the PropertyGrid uses for the labels via Reflection.
If you did decorate the property with DisplayNameAttribute("ABC"), you should be able to access DisplayName via GetCustomAttributes(Type, Boolean). Otherwise just use the Name of the PropertyDescriptor.

Cantharides answered 2/3, 2011 at 14:59 Comment(2)
I need to get all grid items to get displayed text... I have many TypeConverters, and some items were dynamically shows/hides... Your suggestion to solve this problem is admissible, but maybe is the other solution... thanks for answer!Anlage
As most general purpose UI elements, the PropertyGrid makes some things very easy and some things impossible. But if you just need access to the object's property names (or display names), you can get those directly from the object via Reflection. (see updated answer)Cantharides
D
1

I know this is an old question, but I have just encountered the same issue and solved it using this code (suppose PropertyGrid variable is called grid):

public void IteratePropertyGrid()
{
    GridItemCollection categories;
    if (grid.SelectedGridItem.GridItemType == GridItemType.Category)
    {
        categories = grid.SelectedGridItem.Parent.GridItems;
    }
    else
    {
        categories = grid.SelectedGridItem.Parent.Parent.GridItems;
    }

    foreach (var category in categories)
    {
        if (((GridItem)category).GridItemType == GridItemType.Category)
        {
            foreach (GridItem gi in ((GridItem)category).GridItems)
            {
                // Do something with gi                         
            }
        }
    }
}

Of course, this example can be used with simple property grid which has only one level of categories.

Dedicate answered 3/8, 2018 at 10:23 Comment(1)
The top answer only gave me one category whereas your answer gave me all the items in the grid - upvoted thanks!Provide

© 2022 - 2024 — McMap. All rights reserved.