문제

실버 라이트 앱에 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가 출시 될 때까지 무언가를 수행 할 때.

모든 도움이 감사하겠습니다.

도움이 되었습니까?

해결책

나는 내 자신의 문제를 해결했다고 믿는다.

여러 구독 대신 나는 이것을 위해 갔다.

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

나는이 질문이 1 살이라는 것을 알고 있지만, 내가 뭔가를 놓쳤는지 또는이 답변이 작동하는지 알고 싶습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top