Jazimov
Jazimov

Reputation: 13292

Reflection Help Needed: GetProperty Returns Unexpected Type

I am working with the .NET PropertyGrid object. At runtime, I need to inspect the Label property for the PropertyGrid's PropertyGridView.SelectedGridEntry object.

The first problem is that SelectedGridEntry is not a public property--it appears to be internal. So I needed to resort to reflection. I believe I successfully obtained a PropertyGridView instance object using this simple line of code:

var gridView = PropertyGrid.Controls[2];

(Let's accept for the dubious assumption that the PropertyGridView object always is available at PropertyGrid.Controls1.)

Reflection aside for the moment, I used the Visual Studio 2017 debugger at runtime to inspect the PropertyGrid's PropertyGridView object. Here is the image of that:

enter image description here

This image shows that the gridView object has a property called SelectedGridEntry. Notice its type is System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry. Unfortunately, I cannot cast to the PropertyDescriptorGridEntry type because I cannot get access to the System.Windows.Forms.PropertyGridInternal namespace (Microsoft doesn't make that available, it seems).

In an effort to obtain the SelectedGridEntry object, I used this line of code:

var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);

Unfortunately, this returns a var of type GridEntry:

enter image description here

I don't understand why the type obtained through reflection isn't the expected PropertyDescriptorGridEntry type. And since I can't seem to gain access to the namespace I need, I can't cast the GridEntry object to a PropertyDescriptorGridEntry object.

How can I assign a local variable to the SelectedGridEntry object and ensure it's the correct PropertyDescriptorGridEntry type? I feel if I succeed in doing that, I then can obtain that object's Label property value...

Upvotes: 2

Views: 724

Answers (1)

Ňuf
Ňuf

Reputation: 6217

Property can return object of a type that is equal, or derived from, the type of that property. This is allowed by mechanism, that is in Object-oriented programming called Polymorphism.

Inheritance chain of a type PropertyDescriptorGridEntry looks like this:

Object => GridItem => GridEntry => PropertyDescriptorGridEntry

So property SelectedGridEntry, that is of type GridEntry, can return object of type PropertyDescriptorGridEntry, because it is derived from GridEntry. This also means, that this object inherited all properties of it's parent types, includig Label property (that is defined in GridItem class). Therefore the fact, that PropertyDescriptorGridEntry type is internal to the System.Windows.Forms assembly and is not publicly visible in irrelevant, because you can cast this object to GridItem (which is public) and read content of the Label from there with the following:

var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);
var gridEntry = (GridItem)selectedGridEntry.GetValue(PropertyGrid.Controls[2‌​]);
var label = gridEntry.Label;

Upvotes: 1

Related Questions