Bu sizi çalıştırıp çalıştırabilir.
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));
GÜNCELLEME İşte
bir kanıtlanabilir/tekrarlanabilir birim testidir güncelleştirilmiş örnektir. Umarım doğru
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);
}
}
}
içinde 1 atlamak almak için gerekli mods görebilirsiniz 'keyDown.Buffer' textInput.Buffer'' kapanış seçici için accout etmektir? – supertopi
Hayır, 'Arabellek (2,1)', aynı diziden çakışan çiftleri almak için kullanılan bir kalıptır. Bunu yapmanın diğer yolları Publish(). RefCount() sonra 'shared.Zip (shared.Skip (1), (a, b) => Tuple.Create)' ya da 'Scan' kullanmak ancak Buffer (2, 1) '' etrafında çok az çözülüyor. –
Eh, bu çok yakın, ama ... İlk kez girdiğimde "* aaa *" "aaa" gibi bir şey elde ediyorum. Bundan sonra "*" giriyorum ve "**" yi alıyorum, sonra "bbb *" yazıp "* bbb * bbb * bbb", sonra beş kez "* ccc", yedi kez "* ddd" yazdım. . Aradaki arabelleği temizlemenin bir yolu olmalı. – okieh