1

我在 Silverlight 应用程序中启用了 2 点触控画布。我需要做的是,当一个人同时按住(按住并按住)两个画布时,屏幕上的值会增加一次。这应该发生在每个“双重”持有上。我可以使用正常事件来做到这一点,但尝试使用 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将事件配对,因此需要我在再次握住它们之前释放左右。如果我正确释放并再次按住它,则此可观察对象将不会再次触发。
  • 我也认为保持事件只触发一次,因此不需要 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);

我知道这个问题已经有一年了,但我很想知道我是否遗漏了什么或者这个答案是否有效。

于 2011-03-28T23:49:06.527 回答