【问题标题】:How to enumerate PropertyGrid items?如何枚举 PropertyGrid 项目?
【发布时间】:2011-03-02 14:49:39
【问题描述】:

我有一个PropertyGrid,并为其分配了一些对象。

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

我想获取所有网格项,就像我可以获取 selectedGridItem 属性一样:

var selectedProperty = prpGrid.SelectedGridItem;

我可以这样做吗?

【问题讨论】:

  • 令人惊讶的是,这似乎是完全不可能的。

标签: c# .net winforms propertygrid


【解决方案1】:

下面是一段代码,它将检索属性网格的所有 GridItem 对象:

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

    object view = grid.GetType().GetField("gridView", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(grid);
    return (GridItemCollection)view.GetType().InvokeMember("GetAllGridEntries", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, view, null);
}

当然,由于这是使用 Property Grid 的一个未记录的私有字段,因此不保证将来可以工作 :-)

获得所有 GridItem 后,您可以使用 GridItem.GridItemType 属性过滤它们。

【讨论】:

    【解决方案2】:

    如果你只需要对象的属性,你可以通过反射获得:

    PropertyDescriptorCollection myObjectProperties = TypeDescriptor.GetProperties(myObject);
    

    如果您确实使用BrowsableAttribute(false) 隐藏了某些属性,则可以使用GetProperties(Type, Attribute[]) 将其过滤掉。

    我不知道返回 GridItem 集合的方法。

    更新
    当然,您也可以通过 Reflection 获取 PropertyGrid 用于标签的字符串。
    如果您确实使用DisplayNameAttribute("ABC") 装饰了该属性,您应该能够通过GetCustomAttributes(Type, Boolean) 访问DisplayName。否则,只需使用 PropertyDescriptor 的名称。

    【讨论】:

    • 我需要获取所有网格项目才能显示文本...我有很多 TypeConverter,有些项目是动态显示/隐藏的...您解决此问题的建议是可以接受的,但也许是其他解决方案...感谢您的回答!
    • 作为最通用的 UI 元素,PropertyGrid 使一些事情变得非常简单,而一些事情变得不可能。但是,如果您只需要访问对象的属性名称(或显示名称),则可以通过反射直接从对象中获取这些名称。 (见更新的答案)
    【解决方案3】:

    我知道这是一个老问题,但我刚刚遇到了同样的问题并使用此代码解决了它(假设PropertyGrid 变量被称为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                         
                }
            }
        }
    }
    

    当然,这个例子可以用于只有一级类别的简单属性网格。

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 2013-05-15
      • 2013-12-06
      • 2020-02-21
      相关资源
      最近更新 更多