我为我的Windows 8应用程序according to this guide实施行为的修改版本。它的工作原理,除了一个地方,需要无功框架:如何在没有Reactive框架的情况下将事件动态绑定到WinRT中的命令?
protected override void OnAttached()
{
var evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
Observable.FromEventPattern<RoutedEventArgs>(AssociatedObject, Event)
.Subscribe(se => FireCommand());
}
base.OnAttached();
}
的问题很简单,如何实现类似funcitonality没有反应frmaework?我浏览了Rx的来源,可能是obtained here,但我对我来说太复杂了。
我也成功移植,唯一的问题代码,它仅适用于固定式事件处理程序的工作:
protected override void OnAttached()
{
EventInfo evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
AssignEvent<ItemClickEventHandler>(AssociatedObject, Event, FireCommand);
}
base.OnAttached();
}
protected void AssignEvent<T1>(object instance, string eventName, T1 handler)
{
EventInfo runtimeEvent = instance.GetType().GetRuntimeEvent(eventName);
Func<T1, EventRegistrationToken> add = a => (EventRegistrationToken)runtimeEvent.AddMethod.Invoke(instance, new object[] { a });
Action<EventRegistrationToken> remove = a => runtimeEvent.RemoveMethod.Invoke(runtimeEvent, new object[] { a });
WindowsRuntimeMarshal.AddEventHandler(add, remove, handler);
}
任何想法,如何使它动态的,所以我没有用具体的事件处理程序“ItemClickEventHandler”?注意在经典.NET这很简单,但在WinRT中我不能使用Delegate.CreateDelegate(...)
更新: 由于布兰登我能完成的方法,现在看起来像这样:
protected override void OnAttached()
{
EventInfo evt = AssociatedObject.GetType().GetRuntimeEvent(Event);
if (evt != null)
{
MethodInfo addMethod = evt.AddMethod;
MethodInfo removeMethod = evt.RemoveMethod;
ParameterInfo[] addParameters = addMethod.GetParameters();
Type delegateType = addParameters[0].ParameterType;
Action<object, object> handler = (s, e) => FireCommand(e as RoutedEventArgs);
MethodInfo handlerInvoke = typeof(Action<object, object>).GetRuntimeMethod("Invoke", new[] { typeof(object), typeof(object) });
Delegate @delegate = handlerInvoke.CreateDelegate(delegateType, handler);
Func<object, EventRegistrationToken> add = a => (EventRegistrationToken)addMethod.Invoke(AssociatedObject, new object[] { @delegate });
Action<EventRegistrationToken> remove = t => removeMethod.Invoke(AssociatedObject, new object[] { t });
WindowsRuntimeMarshal.AddEventHandler(add, remove, handler);
}
base.OnAttached();
}
现在我可以删除800kB的Rx dll,再次感谢!
删除Rx代码的任何特定原因?我认为有一个核心的Rx库甚至可以在RT上运行? – Brandon
首先,我想将我的应用程序包的大小减少到一半,并且我想知道,它是如何在内部工作的。 –
是否需要通过'WindowsRuntimeMarshal.AddEventHandler()'注册事件处理程序?如果我们可以调用EventInfo对象的'Add'和'Remove'方法,解决这个问题并不难。 – Brandon