سؤال

لدي 2 اللمس تمكين قماش 'في تطبيق Silverlight. ما أحتاج إليه هو عندما يحمل الشخص (يضغط ويحافظ على الضغط) كلا الحوافين في نفس الوقت زيادة قيمة على الشاشة مرة واحدة. يجب أن يحدث هذا لكل "مزدوج" عقد. يمكنني أن أفعل ذلك جيدا باستخدام الأحداث العادية ولكن حاول كتابة نفس الشيء باستخدام 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();
        });

وكانت وظيفة ديوخيك الأساسية للغاية مثل هذا ....

    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