mardi 2 juin 2020

Why can't I get the MouseDown event of a Control via Reflection

I try to remove a EventHandler with .NET Reflection. When I use my own testclass (changed the argument from Control that to TestClass that), it works.

But when I want to do it with a WindowsForms Control, I can't get the public field of the event (strictly speaking I dont get any public instance field). What differs between my TestClass and a WindowsForms Control. The "MouseDown" event and the event in my TestClass are both public.

        static void  RemoveHandler( Control that )
        {
            //adding an eventhandler for testing
            that.MouseDown += (obj,arg) => { };

            string eventName = "MouseDown";
            //this works, but I need the Field, to get the Invocationlist
            var testEventInfo = that.GetType().GetEvent( eventName, BindingFlags.Public | BindingFlags.Instance );

            if ( testEventInfo != null )
            {
                //this fails, Declaring Type of my Event "MouseDown" is Control  testEventFieldInfo stays null
                var testEventFieldInfo = testEventInfo.DeclaringType.GetField( testEventInfo.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField );

                //trying to get all public events fails too, fields is always empty
                // var fields = testEventInfo.DeclaringType.GetFields( BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField );
                if ( testEventFieldInfo != null )
                {
                    var testEventFieldValue = (System.Delegate)testEventFieldInfo.GetValue( that );
                    if ( testEventFieldValue != null ) // if its null no Delegates are hooked
                    {
                        var invocationList = testEventFieldValue.GetInvocationList();
                        //var removeMethod = testEventInfo.GetRemoveMethod();

                        foreach ( var eventHandlerDelegate in invocationList )
                        {

                            testEventInfo.RemoveEventHandler( that, eventHandlerDelegate );
                        }
                    }
                }
            }
        }

What I tried is dealing with inheritance. (TestClass is a drived Class, and the base Class declares the event) Found out that .GetEvent gets also Event from all base classes, but GetField does not, so I added the access to the .DeclaringType of the Field. All this works with my TestClass, but not with a Control-derrived type (i.e. Button or ListBox)

What I found out too is, that there is a field "EventMouseDown", which is NonPublic and Static. But I cant find any Documentation on this. And the Name I hooked on is "MouseDown"

So maybe you know, where is my lack of knowledge. Thank you very much.





Aucun commentaire:

Enregistrer un commentaire