Reputation: 4523
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 RemoveClickEvent
in the accepted answer for a better understanding.
Upvotes: 2
Views: 3614
Reputation: 2540
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);
Upvotes: 3
Reputation: 2683
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.
Upvotes: 0