1

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のいずれかが解放されるまで何かを実行します。

どんな助けでもいただければ幸いです。

4

2 に答える 2

2

私は自分の問題を解決したと信じています。

複数のサブスクライブではなく、これに行きました。

        leftHold.Zip(rightHold, (a,b) => true)
            .TakeUntil(leftRelease.Amb(rightRelease))
            .Subscribe(_ => TextOutput.Text = (Convert.ToInt32(TextOutput.Text) + 1).ToString());

それは私が望むことをしているように見えますが、私はさらなる提案/改善を受け入れています.

于 2010-03-11T12:57:55.793 に答える
2

私はこの答えに出くわし、意味がないと思いました:

    leftHold.Zip(rightHold, (a,b) => true)
        .TakeUntil(leftRelease.Amb(rightRelease))
        .Subscribe(_ => TextOutput.Text =
            (Convert.ToInt32(TextOutput.Text) + 1).ToString());
  • Zipイベントをペアにするので、もう一度保持する前に左右を離す必要があります。私が右を放してもう一度それを保持すると、このオブザーバブルは再び発火しません。
  • また、ホールド イベントは 1 回しか発生しないので、 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 年前のものであることは承知していますが、何か見逃していないか、またはこの回答が機能しているかどうかを知りたいです。

于 2011-03-28T23:49:06.527 に答える