private TiResponse addEventListener(TiRequestParams data) { if (!data.ContainsKey("handle")) { throw new ReflectionException("\"addEventListener\" request missing \"handle\" param"); } string handle = (string)data["handle"]; object instance = InstanceRegistry.getInstance(handle); if (instance == null) { throw new ReflectionException("\"addEventListener\" request invalid handle \"" + handle + "\""); } if (!data.ContainsKey("name")) { throw new ReflectionException("\"addEventListener\" request missing \"name\" param"); } string eventName = (string)data["name"]; var eventInfo = instance.GetType().GetEvent(eventName); // create an array of parameters based on the event info var parameters = eventInfo.EventHandlerType.GetMethod("Invoke").GetParameters(). Select((p, i) => Expression.Parameter(p.ParameterType, "p" + i)).ToArray(); // construct a new array of parameters to the method we are actually going to call // need to pass in extra information so the Proxy knows which callback to fire Expression[] pass = new Expression[5]; parameters.CopyTo(pass, 0); pass[2] = Expression.Constant(eventInfo.Name); pass[3] = Expression.Constant(handle); pass[4] = Expression.Constant(InstanceRegistry.getInstance("browser")); // Get method info of the handler we want to call MethodInfo methodInfo = this.GetType().GetMethod("eventHandler", BindingFlags.NonPublic | BindingFlags.Instance); MethodCallExpression methodCall = Expression.Call(Expression.Constant(this), methodInfo, pass); // Construct a delegate using a lambda expression // (Object, EventArgs) => dummyHandler(Object, EventArgs, String, String, WebBrowser) var lambda = Expression.Lambda( eventInfo.EventHandlerType, methodCall, parameters ).Compile(); // Hook the event to the delegate eventInfo.AddEventHandler(instance, lambda); // Store the delegate to remove it later InstanceRegistry.addDelegate(handle + "." + eventName, lambda); return(null); }