これを少しずつ分解していきましょう。
まず、Observable としてキーを押す必要があります。
var keys =
Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>(
a => this.KeyDown += a,
a => this.KeyDown -= a
).Select(ea => ea.EventArgs)
.Publish();
var unsubscription = keys.Connect();
キープレスの受信に基づいて、バッファリングを描写する条件があります。
Func<KeyEventArgs, bool> isDelimiter =
k => k.KeyCode == Keys.Oemcomma;
これで、バッファ条件が満たされるたびに通知を受け取ることができますkeys.Where(isDelimiter)
区切り文字が検出された場合、または入力が与えられないまでしばらく時間が経過した場合は、バッファを閉じる必要があります。
Observable.Amb(keys.Where(isDelimiter), keys.Throttle(TimeSpan.FromMilliseconds(2000))
これらを組み合わせて、これらの条件で発生する文字のウィンドウを作成できます。
var windows =
keys.Window(keys.Where(isDelimiter),
first => Observable.Amb(
keys.Where(isDelimiter),
keys.Throttle(TimeSpan.FromMilliseconds(2000)
)
.Where(_ => isDelimiter(first))));
あとは、ウィンドウが閉じるまでバッファリングを続け、バッファリング中に残りのコントロールがキーを受信しないようにブロックするだけです。
windows
.SelectMany(window => window
.Do(ka => ka.SuppressKeyPress = true)
.Buffer(() => Observable.Never<KeyEventArgs>())
)
.Subscribe(buf => Trace.WriteLine(new string(buf.Select(ka => (char)ka.KeyValue).ToArray())));
SelectMany
バッファリングされたキープレスの最終ストリームを取得し、最終的にプログラムロジックを配置できます。ここでは、単純にリストを文字列として Trace に出力しました。