Pregunta

Tengo 2 toque habilitado lienzo en una aplicación Silverlight. Lo que tengo que hacer es cuando una persona lleva a cabo (prensas y continúa con la presión) ambos lienzos al mismo tiempo incrementar un valor en la pantalla una vez. Esto debería ocurrir para cada bodega "doble". Puedo hacer eso muy bien usar eventos normales pero trató de escribir lo mismo usando RX y estoy quedarse atascado.

En la actualidad mi código es idéntico al enfoque de eventos por separado (el uso de variables globales y método global), pero creo que tiene que haber una mejor manera de componer esto. ¿Puede alguien sugerir un mejor enfoque?

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

Y la función muy básica DoCheck se parece a esto ....

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

Esperamos que usted puede ver lo que estoy tratando de hacer. Cada lienzo tiene un evento de retención y liberación de modo que cuando HoldLeft y HoldRight se llevan a cabo tanto hacer algo hasta que HoldRight o HoldLeft se es liberado.

Cualquier ayuda sería apreciada.

¿Fue útil?

Solución

Creo que he resuelto mi propio problema.

En lugar de los múltiples suscribe Fui para esto.

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

Parece que hacer lo que quiero, pero estoy abierto a otras sugerencias / mejoras.

Otros consejos

Me encontré con esta respuesta y pensaba que no tenía sentido:

    leftHold.Zip(rightHold, (a,b) => true)
        .TakeUntil(leftRelease.Amb(rightRelease))
        .Subscribe(_ => TextOutput.Text =
            (Convert.ToInt32(TextOutput.Text) + 1).ToString());
  • pares Zip hasta eventos también lo haría requiero que os suelte la izquierda y la derecha antes de la celebración de nuevo. Si Solté la derecha y el celebrado de nuevo este observables no dispararía de nuevo.
  • También podría pensar que la bodega sólo los eventos disparar una vez, por lo que hay No debería haber ninguna necesidad de una TakeUntil llamada.
  • También no ver cómo esta respuesta se refire - parece que se pondrá único valor.

Esto es una 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);

Sé que esta pregunta es un año de edad, pero me gustaría saber si me he perdido algo o si esta respuesta funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top