2016-03-31 13 views
0

キー "LeftShift + OemPlus" への鍵 "LeftShift + OemPlus" からバッファのTextInputイベント:.NET 4.6、C#の、WPF、ReactiveExtension 2.2.5RX:使用

私のバーコード・スキャナは、開始と終了の文字を送信(コード39、これが*文字です)。 PreviewKeyUp-Eventを使用するときのキーは、 "LeftShift + OemPlus"です。私はReactiveExtensionsを使用しようとしますが、2つのキーを取得する方法を正確にはわかりません。これはこれまでの私のコードです:

IObservable<EventPattern<KeyEventArgs>> keyDown = 
       Observable.FromEventPattern<KeyEventArgs>(this, "PreviewKeyDown"); 
IObservable<EventPattern<TextCompositionEventArgs>> textInput = 
       Observable.FromEventPattern<TextCompositionEventArgs>(this, "PreviewTextInput"); 
var textInputBuffer = textInput.Buffer(() => 
        keyDown.FirstOrDefaultAsync(t => t.EventArgs.Key == Key.OemPlus)); 

私は "textInputBuffer"を購読することができますが、これは半分しかありません。キー "LeftShift"とそのキー "OemPlus"の直後にバッファを開始し、同じキーのシーケンスで終了します。誰か考えている人?

答えて

0

これは、あなたを起動して実行する可能性があります。

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); 
     } 
    } 
} 
+0

それを得るために必要な改造を見ることができます' textInput.Buffer'における終値セレクタのためaccoutするのですか? – supertopi

+0

いいえ、 'Buffer(2,1)'は同じシーケンスから重複するペアを得るためのパターンです。それ以外の方法は、Refresh()で 'shared.Zip(shared.Skip(1、a、b)=> Tuple.Create)'を使うか、 'Scan'を使うが、' Buffer(2、 1) 'ははるかに少ないです。 –

+0

まあ、これはとても近いですが...初めて「* aaa *」と入力すると、「* aaa」のようなものが得られます。その後、「*」と入力して「**」を入力し、「bbb *」と入力して「* bbb * bbb * bbb」とし、5回「* ccc」、7回「* ddd」などとします。間にバッファをクリアする方法が必要です。 – okieh