Skip to content

Instantly share code, notes, and snippets.

@waynebaby
Created August 9, 2013 01:41
Show Gist options
  • Save waynebaby/6190494 to your computer and use it in GitHub Desktop.
Save waynebaby/6190494 to your computer and use it in GitHub Desktop.
如何用一个方法 将任意eventarg类型的EVent 绑定到一个 Action<object,object> /*支持 windows RT 下的 托管/非托管 EVENT*/
public static IDisposable BindEvent(this object sender, string eventName, EventHandlerInvoker executeAction)
{
var t = sender.GetType();
while (t != null)
{
var es = t.GetEventsFromCache();
EventInfo ei = es.MatchOrDefault(eventName);
if (ei != null)
{
var handlerType = ei.EventHandlerType;
var eventMethod = handlerType.GetMethodsFromCache().MatchOrDefault("Invoke");
if (eventMethod != null)
{
var pts = eventMethod.GetParameters().Select(p => p.ParameterType).ToArray();
var newHandler = CreateHandler(
(o, e) => executeAction(o, e),
handlerType,
pts
);
#if NETFX_CORE ||WINDOWS_PHONE_8
var etmodule = ei.EventHandlerType.GetTypeOrTypeInfo().Module;
if (etmodule.Name == "mscorlib.dll")
{
return DoNetEventBind(sender, ei, newHandler);
}
else
{
var newMI = WinRTEventBindMethodInfo.MakeGenericMethod(newHandler.GetType());
var rval = newMI.Invoke(null, new object[] { sender, ei, newHandler }) as IDisposable;
return rval;
}
#else
return DoNetEventBind(sender, ei, newHandler);
#endif
}
return null;
}
t = t.GetTypeInfo().BaseType;
}
return null;
}
#if NETFX_CORE
static MethodInfo WinRTEventBindMethodInfo = typeof(EventHandlerHelper).GetTypeInfo().GetDeclaredMethod("WinRTEventBind");
private static IDisposable WinRTEventBind<THandler>(object sender, EventInfo ei, object handler)
{
Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken> remove
= et => ei.RemoveMethod.Invoke(sender, new object[] { et });
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler<THandler>(
ev => (System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken)ei.AddMethod.Invoke(sender, new object[] { ev }),
remove,
(THandler)handler);
return new Disposable(() =>
{
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.RemoveEventHandler<THandler>(
remove,
(THandler)handler);
}
);
}
#endif
private static IDisposable DoNetEventBind(object sender, EventInfo ei, Delegate newHandler)
{
ei.AddEventHandler(sender, newHandler);
return new Disposable(() => ei.RemoveEventHandler(sender, newHandler));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment