2

Ok, thanks to ILSpy, I know that the MenuItem class contains an internal class named MenuItemData, which contains itself an internal member named onDrawItem.

Given a MenuItem, I want to retrieve the object corresponding to the member onDrawItem. But all I manage to do is to get the FieldInfo, not the object itself.

Here is my code:

            Dim obj As Object
            Dim fi As FieldInfo
            Dim item as System.Windows.Forms.MenuItem
            Dim mType As System.Type

            mType = item.GetType()

            mType = mType.GetMember("MenuItemData", BindingFlags.NonPublic)(0)

            fi = mType.GetField("onDrawItem", BindingFlags.Static Or BindingFlags.Instance Or BindingFlags.NonPublic)

            obj = fi.GetValue(item)

When reaching the last line, I get an error saying something like that (it's traduced):

The field 'onDrawItem' défined in type 'System.Windows.Forms.MenuItem+MenuItemData' is not a field of the target object of type 'System.Windows.Forms.MenuItem

I don't know what object to pass to the GetValue function on the last line. Any clue?

----EDIT----

My goal is to remove the base eventHandler of the menuItem, named DrawItem. See this post and the function RemoveClickEventin the accepted answer for a better understanding.

Community
  • 1
  • 1
GianT971
  • 4,385
  • 7
  • 34
  • 46

2 Answers2

3
System.Type menuItemType = typeof(System.Windows.Forms.MenuItem);

System.Type menuItemDataType = menuItemType.GetNestedType("MenuItemData",
    System.Reflection.BindingFlags.NonPublic);

System.Reflection.FieldInfo fieldInfoOnDrawItem= menuItemDataType.GetField("onDrawItem", 
    System.Reflection.BindingFlags.NonPublic | 
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.GetField ); 

Addition: To get the value you need a reference to an instance of a MenuItemData. To do this you need to get the value via GetValue of the data field in the MenuItem instance and use that.

System.Windows.Forms.MenuItem menuItem = new System.Windows.Forms.MenuItem();
System.Reflection.FieldInfo fieldInfoData = menuItemType.GetField("data",
    System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.GetField);

object dataField = fieldInfoData.GetValue(menuItem);
object onDrawItem = fieldInfoOnDrawItem.GetValue(dataField);
MaLio
  • 2,498
  • 16
  • 23
  • onDrawItem is defined like that in MenuItemData: internal DrawItemEventHandler onDrawItem; – GianT971 Jun 01 '12 at 14:15
  • You were missing the GetField binding flag, and mType may not be the right nested class. I updated the answer – MaLio Jun 01 '12 at 14:17
  • I added the GetField binding flag, and I get the same error. By the way, I already manage to retrieve the fieldInfo corresponding to onDrawItem. What I need is the correct parameter to pass to fi.GetValue – GianT971 Jun 01 '12 at 14:24
  • to get the value you need a reference to an instance of a MenuitemData. To do this you need to get the value via GetValue of the data field in the MenuItem instance and use that. – MaLio Jun 01 '12 at 14:27
  • The problem is that the menuItemData is returned as a type, not as a field nor a property... – GianT971 Jun 01 '12 at 14:29
  • Yeah, I just saw that too, thx. I will not test your code, but I will accept your answer, cause it is indeed what I needed, the "data" member. – GianT971 Jun 01 '12 at 14:38
0

onDrawItem should be an event, especially given the comment on its declaration type. I found this page on MSDN which should be able to help you out.

Dim tExForm As Type = assem.GetType("ExampleForm")
Dim exFormAsObj As Object = Activator.CreateInstance(tExForm)
Dim evClick As EventInfo = tExForm.GetEvent("Click")
Dim tDelegate As Type = evClick.EventHandlerType
Dim miHandler As MethodInfo = GetType(Example).GetMethod("LuckyHandler", BindingFlags.NonPublic Or BindingFlags.Instance)

Its that last bit that should be the most useful for you. Get the method info for the method linked to the event, which you can then use to either fire off the method, or link to it.

Update This page might also help.

Nevyn
  • 2,623
  • 4
  • 18
  • 32