Created
August 9, 2013 01:41
-
-
Save waynebaby/6190494 to your computer and use it in GitHub Desktop.
如何用一个方法 将任意eventarg类型的EVent 绑定到一个 Action<object,object> /*支持 windows RT 下的 托管/非托管 EVENT*/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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