これは、あなたを起動して実行する可能性があります。
var keyDown = Observable.FromEventPattern<KeyEventArgs>(this, "PreviewKeyDown");
var textInput = Observable.FromEventPattern<TextCompositionEventArgs>(this, "PreviewTextInput");
//Listen to pairs of events
var boundaryEvent = keyDown.Buffer(2,1)
//Only yeild the pair of events if the pair is LeftShift and OemPlus
.Where(buffer =>
buffer[0].EventArgs.Key == Key.LeftShift
&& buffer[1].EventArgs.Key == Key.OemPlus);
var query = from start in boundaryEvent
from text in textInput.Buffer(()=>boundaryEvent)
select text;
//Or
//var query = boundaryEvent.SelectMany(_=>textInput.Buffer(()=>boundaryEvent));
UPDATE
ここで証明可能/反復ユニットテストで更新されたサンプルです。うまくいけば、あなたはkeyDown.Buffer` `にスキップ1右
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Reactive.Testing;
using NUnit.Framework;
namespace StackOverflow.Q36340516_BufferedByBoundary
{
[TestFixture]
public class BufferByBoundary : ReactiveTest
{
[Test]
public void Should_yield_only_text_between_KeyPress_Boundary_events()
{
var scheduler = new TestScheduler();
var observer = scheduler.CreateObserver<string>();
//var keyDown = Observable.FromEventPattern<KeyEventArgs>(this, "PreviewKeyDown");
//var boundaryEvent = keyDown.Buffer(2, 1)
// //Only yield the pair of events if the pair is LeftShift and OemPlus
// .Where(buffer =>
// buffer[0].EventArgs.Key == Key.LeftShift
// && buffer[1].EventArgs.Key == Key.OemPlus)
// .Select(_=>Unit.Default);
var boundaryEvent = scheduler.CreateHotObservable(
OnNext(0150, Unit.Default), //open
OnNext(0350, Unit.Default), //close
OnNext(0550, Unit.Default), //open
OnNext(0850, Unit.Default)); //close
//var textInput = Observable.FromEventPattern<TextCompositionEventArgs>(this, "PreviewTextInput")
// .Select(evt=>evt.EventArgs.Text);
var textInput = scheduler.CreateHotObservable(
OnNext(00100, "A"), //before 1st open
OnNext(00200, "B"), //buffer 1
OnNext(00300, "C"), //buffer 1
OnNext(00400, "D"),
OnNext(00500, "E"),
OnNext(00600, "F"), //buffer 2
OnNext(00700, "G"), //buffer 2
OnNext(00800, "H") //buffer 2
);
var query = from start in boundaryEvent.Take(1)
from text in textInput.Buffer(() => boundaryEvent)
select string.Join(string.Empty, text);
query.Take(1).Repeat().Subscribe(observer);
scheduler.Start();
CollectionAssert.AreEqual(new[]
{
OnNext(350, "BC"),
OnNext(850, "FGH"),
},
observer.Messages);
}
}
}
それを得るために必要な改造を見ることができます' textInput.Buffer'における終値セレクタのためaccoutするのですか? – supertopi
いいえ、 'Buffer(2,1)'は同じシーケンスから重複するペアを得るためのパターンです。それ以外の方法は、Refresh()で 'shared.Zip(shared.Skip(1、a、b)=> Tuple.Create)'を使うか、 'Scan'を使うが、' Buffer(2、 1) 'ははるかに少ないです。 –
まあ、これはとても近いですが...初めて「* aaa *」と入力すると、「* aaa」のようなものが得られます。その後、「*」と入力して「**」を入力し、「bbb *」と入力して「* bbb * bbb * bbb」とし、5回「* ccc」、7回「* ddd」などとします。間にバッファをクリアする方法が必要です。 – okieh