如何自动生成WPF事件的扩展方法库 - >的IObservable

时间:2013-02-16 11:50:49

标签: c# .net wpf events system.reactive

我几乎专门在我的C#WPF应用程序中使用Reactive Extensions。添加和删​​除事件处理程序是一种反模式,我完全嫉妒F#事件实现IObservable的事实。

为了帮助C#开发人员,RX人员提供了以下方法(以及其他一些不同类型的安全性)

public static 
IObservable<EventPattern<TEventArgs>> 
FromEventPattern<TDelegate, TEventArgs>
    ( Action<TDelegate> addHandler
    , Action<TDelegate> removeHandler
)
where TEventArgs : EventArgs

http://msdn.microsoft.com/en-us/library/hh211731(v=vs.103).aspx

我会像这样使用它

var movingEvents = Observable.FromEventPattern<MouseEventHandler, 
    MouseEventArgs>(h => this.MouseMove += h, h => this.MouseMove -= h);

然而这很乏味。我希望能够做的是

var movingEvents = h.MouseMoveObserver();

并完成它。这种扩展方法看起来像

IObservable<MouseEventArgs> MouseMoveObserver(this Canvas This){
    return Observable.FromEventPattern<MouseEventHandler, 
    MouseEventArgs>(h => This.MouseMove += h, h => This.MouseMove -= h); 
}

这不是火箭科学,我一直在考虑建立一个库,我可以根据需要一次添加这些扩展方法。但是我确信一些智能cookie可以编写一个T4模板,通过反射处理WPF库中的所有控件,并生成我需要的所有扩展方法。我的问题是......

是否有人编写过这样的代码生成器来将事件映射到上面的可观察对象,如果不是,有人会对如何做到这一点有任何建议吗?关于.Net反射,我不是很好,但是一些种子代码可能会让我开始。

1 个答案:

答案 0 :(得分:6)

要获取从FrameworkElement派生的所有类型,可以使用

var typesToDo = from t in Assembly.GetAssembly(typeof(FrameworkElement)).GetTypes()
                where t.IsSubclassOf(typeof(FrameworkElement)) 
                        && t.IsPublic 
                        && t.GetEvents().Any()
                select t;

然后您可以使用type.GetEvents()来获取每种类型的事件。您获得的EventInfo将让您查看名称,类型,参数等内容。

你需要做一些额外的工作来应对通用事件,但这不是一个巨大的数额。

我已将example program up on GitHubexample of the output放在一起。

存在一些输出无法正常工作的风险,我还没有尝试过它们:)我确实确保它们都构建完成,并且至少其中一些输出正常工作。