我一直在玩 Windows Phone 7 中的响应式扩展 (RX),并且非常接近一个可行的解决方案,但被一个小细节所吸引。我正在尝试使用Touch.FrameReported和Observable.FromEvent
(更好地学习 Touch API 和 RX 的一些教育任务)处理原始触摸事件,但我只想在某些条件下处理这些事件。例如,我可能只想在枢轴控件中选择特定页面时过滤对 touch down 和 touch up 事件的订阅,但它可以是任何在真假之间来回变化的任意条件。由于条件是一个随时间变化的值,因此感觉它应该是另一个与触摸事件流合并的可观察对象,但我一生都无法弄清楚如何做到这一点。
TakeWhile
相反,我有一个使用 IObservable和SkipUntil
扩展的半工作解决方案。我有一个接收整个应用程序的所有触摸事件的oTouchApp
流oTouchPage
(oTouchDown
( oTouchDown
) 行动。所有这些流都是 type 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 方法可能会更好,但是您可能必须处理“流的流”。我现在正在一个相关问题中与之抗争。