AttachedCommandBehavior.EventHandlerGenerator.CreateDelegate C# (CSharp) Method

CreateDelegate() public static method

Generates a delegate with a matching signature of the supplied eventHandlerType This method only supports Events that have a delegate of type void
public static CreateDelegate ( Type eventHandlerType, MethodInfo methodToInvoke, object methodInvoker ) : Delegate
eventHandlerType System.Type
methodToInvoke System.Reflection.MethodInfo The method to invoke
methodInvoker object The object where the method resides
return System.Delegate
        public static Delegate CreateDelegate(Type eventHandlerType, MethodInfo methodToInvoke, object methodInvoker)
        {
            //Get the eventHandlerType signature
            var eventHandlerInfo = eventHandlerType.GetMethod("Invoke");
            Type returnType = eventHandlerInfo.ReturnParameter.ParameterType;
            if (returnType != typeof (void)) {
                throw new ApplicationException("Delegate has a return type. This only supprts event handlers that are void");
            }

            ParameterInfo[] delegateParameters = eventHandlerInfo.GetParameters();
            //Get the list of type of parameters. Please note that we do + 1 because we have to push the object where the method resides i.e methodInvoker parameter
            Type[] hookupParameters = new Type[delegateParameters.Length + 1];
            hookupParameters[0] = methodInvoker.GetType();
            for (int i = 0; i < delegateParameters.Length; i++) {
                hookupParameters[i + 1] = delegateParameters[i].ParameterType;
            }

            DynamicMethod handler = new DynamicMethod("", null,
                hookupParameters, typeof (EventHandlerGenerator));

            ILGenerator eventIL = handler.GetILGenerator();

            //load the parameters or everything will just BAM :)
            LocalBuilder local = eventIL.DeclareLocal(typeof (object[]));
            eventIL.Emit(OpCodes.Ldc_I4, delegateParameters.Length + 1);
            eventIL.Emit(OpCodes.Newarr, typeof (object));
            eventIL.Emit(OpCodes.Stloc, local);

            //start from 1 because the first item is the instance. Load up all the arguments
            for (int i = 1; i < delegateParameters.Length + 1; i++) {
                eventIL.Emit(OpCodes.Ldloc, local);
                eventIL.Emit(OpCodes.Ldc_I4, i);
                eventIL.Emit(OpCodes.Ldarg, i);
                eventIL.Emit(OpCodes.Stelem_Ref);
            }

            eventIL.Emit(OpCodes.Ldloc, local);

            //Load as first argument the instance of the object for the methodToInvoke i.e methodInvoker
            eventIL.Emit(OpCodes.Ldarg_0);

            //Now that we have it all set up call the actual method that we want to call for the binding
            eventIL.EmitCall(OpCodes.Call, methodToInvoke, null);

            eventIL.Emit(OpCodes.Pop);
            eventIL.Emit(OpCodes.Ret);

            //create a delegate from the dynamic method
            return handler.CreateDelegate(eventHandlerType, methodInvoker);
        }

Usage Example

Beispiel #1
0
        //Creates an EventHandler on runtime and registers that handler to the Event specified
        public void BindEvent(DependencyObject owner, string eventName)
        {
            EventName = eventName;
            Owner     = owner;
            Event     = Owner.GetType().GetEvent(EventName, BindingFlags.Public | BindingFlags.Instance);
            if (Event == null)
            {
                throw new InvalidOperationException(String.Format("Could not resolve event name {0}", EventName));
            }

            //Create an event handler for the event that will call the ExecuteCommand method
            EventHandler = EventHandlerGenerator.CreateDelegate(
                Event.EventHandlerType, typeof(CommandBehaviorBinding).GetMethod("ExecuteCommand", BindingFlags.Public | BindingFlags.Instance), this);
            //Register the handler to the Event
            Event.AddEventHandler(Owner, EventHandler);
        }
All Usage Examples Of AttachedCommandBehavior.EventHandlerGenerator::CreateDelegate
EventHandlerGenerator