Domanda

Ho 2 tocco abilitato su tela in un App Silverlight. Quello che devo fare è quando una persona tiene (presse e continua a premere) entrambe le tele, allo stesso tempo incrementare un valore sullo schermo una volta. Questo dovrebbe avvenire per ogni hold "doppio". Posso farlo bene usando gli eventi normali, ma provato a scrivere la stessa cosa usando RX e sto rimanere bloccati.

Al momento il mio codice è identico a quello approccio eventi separato (usando le variabili globali e metodo globale), ma penso che ci deve essere un modo migliore per comporre questo. Qualcuno può suggerire un approccio migliore?

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

E la funzione molto di base DoCheck assomiglia a questo ....

    private void DoCheck()
    {
        if (_rightHeld && _leftHeld)
        {
            MyTextBox.Text = (Convert.ToInt32(MyTextBox.Text) + 1).ToString() ;
        }
    }

Speriamo che si può vedere quello che sto cercando di fare. Ogni tela è un evento di attesa e di rilascio in modo che quando HoldLeft e HoldRight sono entrambi tenuti fare qualcosa fino a quando HoldRight o HoldLeft vengono viene rilasciato.

Qualsiasi aiuto sarebbe apprezzato.

È stato utile?

Soluzione

Credo di aver risolto il mio problema.

Piuttosto che le molteplici sottoscrive sono andato per questo.

        leftHold.Zip(rightHold, (a,b) => true)
            .TakeUntil(leftRelease.Amb(rightRelease))
            .Subscribe(_ => TextOutput.Text = (Convert.ToInt32(TextOutput.Text) + 1).ToString());

Sembra di fare quello che voglio, ma sono aperto ad ulteriori suggerimenti / miglioramenti.

Altri suggerimenti

Mi sono imbattuto in questa risposta e ho pensato che non aveva senso:

    leftHold.Zip(rightHold, (a,b) => true)
        .TakeUntil(leftRelease.Amb(rightRelease))
        .Subscribe(_ => TextOutput.Text =
            (Convert.ToInt32(TextOutput.Text) + 1).ToString());
  • paia Zip gli eventi in modo sarebbe richiedono che ho comunicato a sinistra e destra prima di tenere di nuovo. Se ho rilasciato a destra e la tenne ancora una volta questo non sarebbe osservabile fuoco ancora una volta.
  • Ho anche potrebbe pensare che la stiva eventi attiva una sola volta, quindi non c'è non dovrebbe essere alcun bisogno di un chiamata TakeUntil.
  • Anche io non vedo come questa risposta sarà refire - sembra avere una sola valore.

Ecco un'alternativa:

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

So che questa domanda è un anno di età, ma mi piacerebbe sapere se ho perso qualcosa o se questa risposta funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top