题
我在 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);
我知道这个问题已经有一年了,但我很想知道我是否错过了一些东西或者这个答案是否有效。
不隶属于 StackOverflow