2012-05-07 12 views
0

私はobservablesを使用してkeydownイベントを処理しています。 消費者が実際に処理した場合は、常に扱いの鍵を設定するオブザーバブルを公開したいと思います。 これは可能ですか?ここでRX - 被験者が基準を満たしている場合にのみコードを実行する

は、私が今扱っキーを設定する方法の例です:

KeyDown.Where(e => e.Key == Keys.W) 
.Subscribe(e => { Console.WriteLine(e.Key); e.Handled = true; }); 

ここで扱わプロパティは自動的にその後設定された場合、私はちょうどキーの代わりKeyDownEventArgsを公開することができ(私はそれを行うしたいと思います方法の例ですあまりにも):

HandledKeyDown.Where(k => k == Keys.W).Subscribe(k => Console.WriteLine(k)); 

ここに私が試したものです:

HandledKeyDown = Observable.Create<Key>(observer => { 
    var keys = KeyDown.Subscribe(e => { e.Handled = true; observer.OnNext(e.Key); }); 
    return() => keys.Dispose(); 
}); 

T消費者が実際に処理したかどうかにかかわらず、キーは常に処理されるように設定されるということです。

コードがサブスクライブ方式に「到達」しているかどうかを知る方法はありますか?

答えて

1

は、サブスクリプションの後に処理として、イベントを作るようにKeyEventArgsにサブスクリプションをオーバーロードすることです。延長のような音:

public static IDisposable SubscribeAndHandle(this IObservable<KeyEventArgs> input, Action<Keys> action) 
{ 
    return input.Subscribe(e => { action(e.KeyCode); e.Handled = true; }); 
} 

は次に、あなただけの代わりにSubscribeSubscribeAndHandleを使用し、アクションが実行された後にのみtrueにHandledを設定し、アクションを使用することができますKeysないKeyEventArgs

var sub = KeyDown 
      .Where(e => e.KeyCode = Keys.W) // and so on 
      .SubscribeAndHandle(k => Console.WriteLine(k)); 

アクションが実行される前にHandledがtrueに設定されていても構わない場合は、拡張メソッドではなくDoを使用できます。 @Enigmativityから有用なコメントは、おそらくあなたがHandledは、サブスクリプション内からtrueまたはしないように設定されているかどうかを決定したいかもしれないことを示唆し

public static IDisposable SubscribeAndHandle(this IObservable<KeyEventArgs> input, Action<Keys> action) 
{ 
    return input.Do(e => e.Handled = true) 
       .Select(e => e.KeyCode) 
       .Subscribe(e => action(e)); 
} 

:これは副作用を実行するクリーンな方法です。これは十分に簡単です、ただFunc<Keys,bool>はなくAction<Keys>受け入れるように拡張メソッドを変更:答えのための

public static IDisposable SubscribeAndHandle(this IObservable<KeyEventArgs> input, Func<Keys,bool> action) 
{ 
    return input.Subscribe(e => e.Handled = action(e.KeyCode)); 
} 
+0

あなたのコードは 'e.Handled'プロパティをtrueに設定します。私は、消費者が実際にそれを処理したと言う論理をOPが望んでいたことを理解しました。これを容易にするには、アクションの署名を 'Func 'に変更する必要があります。 – Enigmativity

+0

私の解釈では、加入者がイベントを受け取って「処理した」ときは、「コードが「subscribeメソッドに達したかどうかを知る方法はありますか?そして彼は加入者がより複雑な 'KeyEventArgs'ではなく単純な' Keys'を受け取ることを望んでいます。 – yamen

+0

これは私が欲しかったものを正確に(最後の部分を必要としなかった、あなたは初めてそれを釘付けにした)。どのように私はそれに尋ねてはならないのか分かりませんが、3人のうち2人が質問を誤解したのは私のせいです。とにかく、ありがとう。 – user974608

0

私はこのような何かをやって見ます:

var HandledKeyDown = 
    KeyDown 
     .Do(e => { /* Handling Code Here */ }) 
     .Where(e => e.Handled) 
     .Where(e => e.Key == Keys.W) 
     .Select(e => e.Key) 
     .Subscribe(k => Console.WriteLine(k)); 

Do拡張メソッドを使う「インターセプト」観測可能なインラインの値ができます。

これが役立つかどうか教えてください。あなたが好きな何

+0

感謝を。 _H_のフィルターだけでなく、任意の基準で_HandledKeyDown_をフィルター処理したいと思います。私が正しく理解すれば、このコマンドはHandledKeyDownだけがWを処理できるようにします。しかし、それについて知ってうれしいです、それは簡単に通常のKeyDownsを扱うようになります。 – user974608

+0

@ user974608 - 'Keys.W'によるフィルタリングは、あなたのコードがそれを持っていたためにしかありません。この解決策が出る限り重要ではありません。私の解決策が動作するには、本当に 'Do'と最初の' Where'節が必要です。 – Enigmativity

+0

サブスクリプション番号に達しているかどうかにかかわらず、「実行する」は実行されますか? 'Where'ステートメントの後に' Do'が観測可能チェーンの下に移動した場合、OPでこれで十分でしょうか?そうでない場合は、どうしてですか? – yamen

関連する問題