Я играл с Reactive Extensions (RX) в Windows Phone 7 и очень близок к рабочему решению, но поймал одну маленькую деталь. Я пытаюсь обработать необработанные сенсорные события, используя Touch.FrameReported и Observable.FromEvent
(что-то вроде образовательного квеста, чтобы лучше изучить Touch API и RX), но я хочу обрабатывать события только при определенных условиях. условия. Например, я могу захотеть отфильтровать подписку по событиям касания и касания только тогда, когда определенная страница выбрана в сводном элементе управления, но это может быть любое произвольное условие, которое изменяется между истиной и ложью. Поскольку условие - это значение, которое меняется со временем, создается впечатление, что оно должно быть еще одной наблюдаемой, которая сливается с потоком событий касания, но я не могу понять, как это сделать.
Вместо этого у меня есть полу-рабочее решение, использующее расширения TakeWhile
и SkipUntil
для IObservable. У меня есть поток, который получает все события касания для всего приложения (oTouchApp
), второй поток, который принимает элементы только при условии, что мое условие фильтрации выполнено (oTouchPage
), а затем два других потока, которые фильтруют касания, касаются вниз (oTouchDown
) и подправить (oTouchDown
) действия. Все эти потоки имеют тип IObservable<IEvent<TouchFrameEventArgs>>
, поэтому их легко объединять и сравнивать для создания пользовательских жестов. Проблема в том, что я не могу перезапустить поток oTouchPage, как только условие фильтра изменится с true на false. Мне пришлось бы вручную воссоздавать поток, где, как я бы предпочел, он как-то переключается между включением и выключением.
Вот код, который у меня есть. Будем весьма благодарны за любую помощь в том, как отфильтровать поток, используя логическое значение (например, включение / выключение).
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");});
UPDATE:
Оказывается, все, что мне было нужно, это добавить простое предложение where в поток oTouchPage: var oTouchPage = oTouchApp.Where((x) => TestCondition == True);
Возможно, это не лучшее решение, поскольку тестовое условие оценивается каждый раз, когда создается элемент, но оно хорошо работает и легко читается. Если тестовое условие основывалось на событиях или каком-либо другом условии, которое было легко преобразовать в IObservable, то я думаю, что упомянутые ниже подходы Window или SelectMany могли бы быть лучше, но тогда вам, возможно, придется иметь дело с «потоком потоков». Я борюсь с этим прямо сейчас в связанном вопросе .