私はWindowsPhone7のReactiveExtensions(RX)で遊んでいて、実用的なソリューションに非常に近いですが、1つの小さな詳細に巻き込まれました。Touch.FrameReportedと(Touch APIとRXをよりよく学ぶための少しの教育的な探求)を使用して生のタッチイベントを処理しようとしていますがObservable.FromEvent
、特定の条件下でのみイベントを処理したいと思います。たとえば、ピボットコントロールで特定のページが選択されている場合にのみ、タッチダウンイベントとタッチアップイベントへのサブスクリプションをフィルタリングしたい場合がありますが、trueとfalseの間で前後に変化する任意の条件である可能性があります。条件は時間の経過とともに変化する値であるため、タッチイベントストリームとマージされる別のオブザーバブルである必要があるように感じますが、それを行う方法を一生理解することはできません。
代わりに、IObservableの拡張機能を使用TakeWhile
した半ば機能するソリューションがあります。SkipUntil
アプリ全体のすべてのタッチイベントを受信するストリーム(oTouchApp
)、フィルタリング条件がtrueの場合にのみアイテムを取得する2番目のストリーム(oTouchPage
)、そしてタッチをタッチダウン(oTouchDown
)とタッチアップにフィルタリングする他の2つのストリームがあります。 (oTouchDown
)アクション。これらのストリームはすべてタイプIObservable<IEvent<TouchFrameEventArgs>>
であるため、簡単にマージして比較し、カスタムジェスチャを作成できます。問題は、フィルター条件がtrueからfalseに変わると、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のアプローチの方が適していると思いますが、「ストリームのストリーム」を処理する必要がある場合があります。私は今、関連する質問でそれと戦っています。