Curiosidad (o no) en WinForms y focus…

Os cuento una curiosidad de la que me acabo de dar cuenta ahora mismo… Un funcionamiento, como mínimo curioso en Winforms… siempre entendiendo como curioso que “yo no lo sabía y mi no encaja en mi (poco) sentido común”.

El titular sensacionalista sería: Control desactivado recibe el focus.

La realidad es que si en el evento “Leave” de un control, desactivamos el siguiente control que debe recibir el foco, este control NO recibe el foco (como es de esperar) pero su evento “Enter” se ejecuta…

… y no sólo eso! La siguiente vez que pulsemos TAB (o que con el mouse pongamos el foco en cualquier otro control incluyendo el propio control que tiene el foco), el evento “Leave” del control deshabilitado se ejecutará!

A partir de aquí, el focus ya no “entrará” ninguna otra vez en el control deshabilitado (no lanzará más eventos Enter/Leave).

Si “quereis” jugar con esta curiosidad, aquí os dejo un pequeño programilla, con el que comprobar in-situ esta curiosidad…

Link al programa para testear la curiosidad. Compilado con VS2008 y .NET 3.5 SP1, bajo Windows XP.

Y una capturilla para que lo veais (al tener la checkbox activa, se deshabilita el textbox que está a la derecha del TextBox con fondo naranja-suave (que he llamado en un alarde de pereza textBox3)):

image

Evidentemente, si alguien tiene más información al respecto y sabe el porqué de esta causa… pues le estaré muy agradecido!!! 😉

Saludos!

4 comentarios sobre “Curiosidad (o no) en WinForms y focus…”

  1. Es muy posible que se deba a que la deshabilitación se haga mediante SendMessage en lugar de PostMessage. SendMessage no retorna hasta que no se haya procesado este.

    Es decir, tu deshabilitas el control desde otro, que en el proceso del su mensaje de salida llama a SendMessage con lo que se vuelve a llamar a la bomba de mensajes de nuevo de forma recursiva. En eso tu cambias de control sin que haya retornado de la segunda llamada y por eso puedes entrar en el control, y cuando retorna de las llamadas tu ya estás dentro y no se puede hacer otra cosa.

    El problema viene de la forma en que .NET controla (o pasa olímicamente) de la bomba de mensajes según le interese. Supongo que Win32 puro y duro no se produce, pero lo voy a probar.

  2. Otra curiosidad relacionada: Si pones un MessageBox antes de desactivar el control mostrando el ActiveControl, te muestra el control desactivado. Si despues de desactivar el segundo control, pones el mismo mesagebox, el control activo cambió al que corresponde.

    Me imagino que el primer messagebox actualiza la vista en su thread (acordate que la vista en .Net corre en un thread aparate. Tendrias que probar trabajar con delegados).

    Buen, blog. Saludos.

  3. Otra curiosidad relacionada: Si pones un MessageBox antes de desactivar el control mostrando el ActiveControl, te muestra el control desactivado. Si despues de desactivar el segundo control, pones el mismo mesagebox, el control activo cambió al que corresponde.

    Me imagino que el primer messagebox actualiza la vista en su thread (acordate que la vista en .Net corre en un thread aparate. Tendrias que probar trabajar con delegados).

    Buen, blog. Saludos.

  4. Hola, gracias a todos por los comentarios 🙂

    @Rafa
    Lo que dices tiene sentido, pero ni idea… quien sabe lo que hará el framework realmente por debajo…

    @Cerebrado
    No termino de entender tu comentario, sorry… igual estoy yo un poco espeso 😛

    Saludos!

Responder a etomas Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *