我在 Silverlight 应用程序中有 2 个支持触摸的 Canvas。我需要做的是,当一个人同时按住(按下并保持按下)两个画布时,屏幕上的值会增加一次。每次“双”握时都应该发生这种情况。我可以使用正常事件很好地做到这一点,但尝试使用 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 称呼。
  • 另外,我看不出这个答案将如何添加 - 似乎只有一个值。

这是一个替代方案:

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);

我知道这个问题已经有一年了,但我很想知道我是否错过了一些东西或者这个答案是否有效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top