RX での複数のイベントの結合
-
19-09-2019 - |
質問
Silverlight アプリで 2 タッチ対応の Canvas を使用しています。私がしなければならないのは、人が両方のキャンバスを同時に押したとき(押し続けたとき)、画面上の値を1回増やすことです。これはすべての「ダブル」ホールドで発生するはずです。通常のイベントを使用して問題なく実行できますが、RXを使用して同じことを書こうとしたところ、行き詰まってしまいました。
現在、私のコードは個別のイベントのアプローチ (グローバル変数とグローバル メソッドを使用) と同じに見えますが、これを構成するより良い方法があるはずだと思います。誰かがより良いアプローチを提案できますか?
var leftHold = Observable.FromEvent<TCanvas.HoldHandler, GestureHoldEventArgs>(
h => new TCanvas.HoldHandler(h),
h => HoldLeft.Hold += h,
h => HoldLeft.Hold += h
);
var rightHold = Observable.FromEvent<TCanvas.HoldHandler, GestureHoldEventArgs>(
h => new TCanvas.HoldHandler(h),
h => HoldRight.Hold += h,
h => HoldRight.Hold += h
);
var rightRelease = Observable.FromEvent<TCanvas.ReleaseHandler, EventArgs>(
h => new TCanvas.ReleaseHandler(e => { }),
h => HoldRight.Release += h,
h => HoldRight.Release += h
);
var leftRelease = Observable.FromEvent<TCanvas.ReleaseHandler, EventArgs>(
h => new TCanvas.ReleaseHandler(e => { }),
h => HoldLeft.Release += h,
h => HoldLeft.Release += h
);
leftHold.Subscribe(e =>
{
_leftHeld = true;
DoCheck();
});
rightHold.Subscribe(e =>
{
_rightHeld = true;
DoCheck();
});
rightRelease.Subscribe(e =>
{
_rightHeld = false;
DoCheck();
});
leftRelease.Subscribe(e =>
{
_leftHeld = false;
DoCheck();
});
そして、非常に基本的な DoCheck 関数は次のようになります...
private void DoCheck()
{
if (_rightHeld && _leftHeld)
{
MyTextBox.Text = (Convert.ToInt32(MyTextBox.Text) + 1).ToString() ;
}
}
私が何をしようとしているのか理解していただければ幸いです。各キャンバスにはホールド イベントとリリース イベントがあるため、HoldLeft と HoldRight の両方がホールドされている場合は、HoldRight または HoldLeft のいずれかがリリースされるまで何かが行われます。
助けていただければ幸いです。
解決
私は、私は私自身の問題を解決したと考えています。
むしろ私はこのために行った複数のサブスクライブよります。
leftHold.Zip(rightHold, (a,b) => true)
.TakeUntil(leftRelease.Amb(rightRelease))
.Subscribe(_ => TextOutput.Text = (Convert.ToInt32(TextOutput.Text) + 1).ToString());
私がやりたいように見えますが、私はさらに提案/改善に開いています。
他のヒント
私はこの答えに出会って、それは意味がないと思いました:
leftHold.Zip(rightHold, (a,b) => true)
.TakeUntil(leftRelease.Amb(rightRelease))
.Subscribe(_ => TextOutput.Text =
(Convert.ToInt32(TextOutput.Text) + 1).ToString());
Zip
イベントをペアアップするため、再び保持する前に左と右をリリースする必要があります。私が正しくリリースして、再びそれを保持した場合、この観察可能は再び発砲しません。- 私はまた、ホールドイベントが一度だけ発砲すると思うので、
TakeUntil
電話。 - また、私はこの答えがどのように反映されるかわかりません - それは1つの価値しか得られないようです。
代替案は次のとおりです。
var left = leftHold.Select(x => true).Merge(leftRelease.Select(x => false));
var right = rightHold.Select(x => true).Merge(rightRelease.Select(x => false));
var bothHold =
left.CombineLatest(right, (l, r) => l && r)
.Where(lr => lr == true)
.Select(lr => (Convert.ToInt32(MyTextBox.Text) + 1).ToString());
bothHold.Subscribe(t => MyTextBox.Text = t);
この質問が 1 年前のものであることは承知していますが、何かを見逃しているのか、それともこの回答が機能するのかを知りたいです。
所属していません StackOverflow