¿La mejor manera de tratar con los usuarios haciendo doble clic en los botones en una aplicación de winforms?

StackOverflow https://stackoverflow.com/questions/255104

Pregunta

Estoy trabajando en una aplicación WinForms y tengo un control de usuario en ella. Los botones en el control de usuario elevan los eventos al formulario que será manejado por otro código. Uno de los botones inicia algunos procesos que causarán problemas si se ejecutan simultáneamente. Tengo lógica en el código para administrar el estado, por lo que normalmente un usuario no puede ejecutar el proceso si ya se está ejecutando. Sin embargo, si el usuario hace doble clic en el botón, iniciará el proceso dos veces tan rápido que es difícil para mí evitarlo.

Me pregunto, ¿cuál es la mejor manera de manejar esto?

Comencé por deshabilitar el botón en el evento de clic, pero el segundo clic entra antes de que el primer clic desactive el botón. La configuración de otras banderas en el código tampoco lo detectó.

Estoy considerando agregar algún tipo de bloqueo de sincronización en el código que provoca el evento, pero me pregunto si alguno de ustedes tiene una idea mejor.

Dado que este proyecto está casi completo, estoy buscando respuestas que no impliquen una reescritura radical de la aplicación (como la implementación del bloque de aplicaciones compuestas), sin embargo, siéntase libre de publicar esas ideas también, ya que puedo usarlas en mis próximos proyectos.

¿Fue útil?

Solución

Asegúrese de que la inhabilitación de su botón o cualquier otro bloqueo que haga sea la primera cosa que haga en el controlador de eventos. Me sorprendería enormemente si pudieras poner en cola dos eventos de clics incluso antes de que se dispare la primera instrucción, pero supongo que eso es posible si estás en una computadora muy lenta que está atascada con otras aplicaciones.

En ese caso, usa una bandera.

private bool runningExclusiveProcess = false;

public void onClickHandler(object sender, EventArgs e)
{
    if (!runningExclusiveProcess)
    {
        runningExclusiveProcess = true;
        myButton.Enabled = false;

        // Do super secret stuff here

        // If your task is synchronous, then undo your flag here:
        runningExclusiveProcess = false;
        myButton.Enabled = true;
    }
}

// Otherwise, if your task is asynchronous with a callback, then undo your flag here:
public void taskCompletedCallback()
{
    runningExclusiveProcess = false;
    myButton.Enabled = true;
}

Si aún puedes obtener dos clics de algo así, entonces asegúrate de no estar suscrito accidentalmente a un evento de doble clic, o cualquier otra cosa que esté sucediendo.

Otros consejos

¿Está manejando el evento dos veces?

Estoy muy sorprendido de leer que está llegando el segundo clic antes de que pueda deshabilitar el botón. Me aseguraría de que no esté conectando el evento dos veces. He hecho esto por accidente antes. Luego obtendrás dos eventos, casi instantáneamente.

La marca de desactivación en ese botón no se establecerá hasta que el controlador de eventos de botón se complete, y cualquier clic adicional se colocará en la cola de mensajes de Windows detrás del primer clic. Asegúrese de que el controlador de eventos del botón se complete rápidamente para liberar el hilo de la interfaz de usuario. Hay varias formas de hacer esto, pero todas involucran la creación de un subproceso o mantener un subproceso de trabajo listo y esperando un AutoResetEvent.

Por casualidad, ¿está etiquetando el botón con un icono? De todos modos, use el código para evitar ejecutar dos procesos a la vez, pero puede reducir el doble clic en el lado humano si su botón se ve y actúa como un botón de comando convencional (rectangular, solo etiqueta de texto, superficie "expuesta" que deprime). un clic). Solo un pensamiento.

Desactive el botón tan pronto como se haga clic. Por lo tanto, el evento no se puede manejar dos veces. Tan pronto como el evento haya sido manejado, puede volver a habilitar el botón.

La respuesta marcada está cerrada, si es anecdótica en el mejor de los casos. Para los que no lo son, le falta mucho código para que tenga sentido. He escrito un artículo sobre el uso de temporizadores y subprocesos y el ejemplo del código es REALMENTE fácil de entender. Intente leerlo y ver si puede establecer los indicadores del ejemplo anterior ejecutando el proceso de su tarea en un nuevo hilo:

http://www.robault.com/category/Threading.aspx

Deshabilite el botón después de que el usuario haga clic en él por primera vez y antes de comenzar la tarea. Cuando la tarea se complete, vuelva a habilitar el botón.

  

Comencé por deshabilitar el botón   en el evento clic, pero el segundo   clic entra antes del primer clic   hace que el botón se deshabilite.   Establecer otras banderas en el código no   atraparlo tampoco.

Dado que WinForms es inherentemente de un solo subproceso, no debería ser posible que el segundo clic se dispare antes de que se haya completado el procesamiento del primer (a menos que esté utilizando nuevos subprocesos o BackgroundWorkers, etc.).

¿Puede mostrarnos una muestra que ilustre su problema?

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