我正在使用.NET PropertyGrid对象。在运行时,我需要检查PropertyGrid的PropertyGridView.SelectedGridEntry对象的Label属性。
第一个问题是SelectedGridEntry不是公共属性 - 它似乎是内部的。所以我需要求助于反思。我相信我使用这一简单的代码行成功获得了一个PropertyGridView实例对象:
var gridView = PropertyGrid.Controls[2];
(让我们接受可疑的假设,即PropertyGrid.Controls 1上的PropertyGridView对象始终可用。)
暂时不反思,我在运行时使用Visual Studio 2017调试器来检查PropertyGrid的PropertyGridView对象。这是图像:
此图显示gridView对象具有名为SelectedGridEntry的属性。请注意,其类型为 System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry 。不幸的是,我无法转换为PropertyDescriptorGridEntry类型,因为我无法访问System.Windows.Forms.PropertyGridInternal命名空间(微软似乎没有提供它,似乎)。
为了获取SelectedGridEntry对象,我使用了以下代码行:
var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);
不幸的是,这会返回 GridEntry 类型的变种:
我不明白为什么通过反射获得的类型不是预期的 PropertyDescriptorGridEntry 类型。由于我似乎无法访问我需要的命名空间,因此我无法将 GridEntry 对象转换为 PropertyDescriptorGridEntry 对象。
如何将局部变量分配给 SelectedGridEntry 对象,并确保它具有正确的 PropertyDescriptorGridEntry 类型?我觉得如果我成功了,我就可以获得该对象的Label属性值......
答案 0 :(得分:1)
属性可以返回类型相同的对象,或从派生的属性,该属性的类型。机制允许这样做,即Object-oriented programming中称为Polymorphism。
类型PropertyDescriptorGridEntry
的继承链如下所示:
Object
=> GridItem
=> GridEntry
=> PropertyDescriptorGridEntry
因此SelectedGridEntry
类型的属性GridEntry
可以返回PropertyDescriptorGridEntry
类型的对象,因为它来自GridEntry
。这也意味着,该对象继承了它的父类型的所有属性,包括Label
属性(在GridItem
类中定义)。因此,事件PropertyDescriptorGridEntry
类型是System.Windows.Forms
程序集的内部类型,并且在不相关的情况下不公开显示,因为您可以将此对象强制转换为GridItem
(这是公共的)并读取内容Label
来自那里:
var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);
var gridEntry = (GridItem)selectedGridEntry.GetValue(PropertyGrid.Controls[2]);
var label = gridEntry.Label;