【发布时间】:2011-06-17 02:13:19
【问题描述】:
我一直在使用 Windows Phone 7 中的响应式扩展 (RX),并且非常接近于一个可行的解决方案,但我发现了一个小细节。我正在尝试使用Touch.FrameReported 和Observable.FromEvent 处理原始触摸事件(更好地学习Touch API 和RX 的教育任务),但我只想在某些条件下处理这些事件。例如,我可能只想在枢轴控件中选择特定页面时过滤对 touch down 和 touch up 事件的订阅,但它可以是任何在真假之间来回变化的任意条件。由于条件是一个随时间变化的值,因此感觉它应该是另一个与触摸事件流合并的可观察对象,但我一生都无法弄清楚如何做到这一点。
相反,我有一个使用 IObservable 的 TakeWhile 和 SkipUntil 扩展的半工作解决方案。我有一个接收整个应用程序的所有触摸事件的流(oTouchApp),第二个流仅在我的过滤条件为真时接收项目(oTouchPage),然后还有两个其他流将触摸过滤为触摸向下 (oTouchDown) 和向上 (oTouchDown) 操作。所有这些流都是IObservable<IEvent<TouchFrameEventArgs>> 类型,因此可以轻松地合并和比较它们以创建自定义手势。问题是一旦过滤条件从真变为假,我就无法重新启动 oTouchPage 流。我必须手动重新创建流,我希望它以某种方式在打开和关闭之间切换。
这是我到目前为止的代码。任何有关如何使用布尔值(如开/关开关)过滤流的帮助将不胜感激。
var oTouchApp = Observable.FromEvent<TouchFrameEventHandler, TouchFrameEventArgs>(x => new TouchFrameEventHandler(x), ev => Touch.FrameReported += ev, ev => Touch.FrameReported -= ev);
//This stops working after TestCondition goes from True to False
var oTouchPage = oTouchApp.SkipWhile((x) => TestCondition == False).TakeWhile((x) => TestCondition == True);
var oTouchDown = from t in oTouchPage
let primarypoint = t.EventArgs.GetPrimaryTouchPoint(this)
where primarypoint.Action == TouchAction.Up
select t;
var oTouchUp = from t in oTouchPage
let primarypoint = t.EventArgs.GetPrimaryTouchPoint(this)
where primarypoint.Action == TouchAction.Down
select t;
//Code for testing
var sub1 = oTouchPage.Subscribe(x =>{Debug.WriteLine("TouchPage");});
var sub2 = oTouchDown.Subscribe(x =>{Debug.WriteLine("TouchDown");});
var sub3 = oTouchUp.Subscribe(x =>{Debug.WriteLine("TouchUp");});
更新:
结果我只需要在 oTouchPage 流中添加一个简单的 where 子句:var oTouchPage = oTouchApp.Where((x) => TestCondition == True);
它可能不是最好的解决方案,因为每次生产项目时都会评估 TestCondition,但它运行良好且易于阅读。如果测试条件基于事件或其他易于转换为 IObservable 的条件,那么我认为下面提到的 Window 或 SelectMany 方法可能会更好,但是您可能必须处理“流的流”。我现在正在related question 中与之抗争。
【问题讨论】:
标签: system.reactive observable