¿Desventaja de configurar Form.KeyPreview = true?

Me pregunto para qué sirve la propiedad Form.KeyPreview. ¿Por qué existe y qué es lo que “arriesgo” al establecerlo en verdadero? Supongo que debe tener algún efecto negativo; de lo contrario, no debería existir en absoluto (o al menos ser cierto por defecto).

EDITAR : Sé perfectamente lo que hace. Estoy preguntando por qué . ¿Por qué tengo que configurarlo para que los eventos de teclado se activen? ¿Por qué los eventos de teclado no siempre se activan en un formulario? ¿Cuál no es solo el comportamiento estándar?

La razón particular por la que pregunto es: Acabo de establecer KeyPreview = true en la forma base de mi aplicación, de la cual heredan todas las demás formas. ¿Estoy preparado para una desagradable sorpresa?

Form.KeyPreview es un poco anacrónico, heredado del modelo de objetos de Visual Basic para el diseño de formularios. En los días VB6, necesitabas KeyPreview para poder implementar KeyPreview de teclado. Ya no es necesario en Windows Forms, anulando ProcessCmdKey() es la mejor solución:

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == (Keys.Control | Keys.F)) { DoSomething(); // Implement the Ctrl+F short-cut keystroke return true; // This keystroke was handled, don't pass to the control with the focus } return base.ProcessCmdKey(ref msg, keyData); } 

Pero KeyPreview fue compatible para ayudar a la legión de progtwigdores de VB6 a cambiar a .NET a principios de los 2000. El objective de KeyPreview o ProcessCmdKey() es permitir que su UI responda a las teclas de método abreviado. Los mensajes de teclado normalmente se envían al control que tiene el foco. El bucle de mensaje de Windows Forms permite que el código eche un vistazo a ese mensaje antes de que el control lo vea. Eso es importante para las teclas de KeyDown , implementar el evento KeyDown para cada control que pueda obtener el foco para detectarlas es muy poco práctico.

Establecer KeyPreview en True no causa problemas. Se KeyDown evento KeyDown del KeyDown , solo tendrá un efecto si tiene un código que hace algo con la pulsación de tecla. Pero tenga en cuenta que sigue de cerca el uso de VB6, no puede ver el tipo de teclas que se utilizan para la navegación. Al igual que las teclas del cursor y Tab , Escape and Enter para un diálogo. No es un problema con ProcessCmdKey() .

Desde MSDN

Cuando esta propiedad se establece en verdadero, el formulario recibirá todos los eventos KeyPress, KeyDown y KeyUp. Una vez que los controladores de eventos del formulario hayan completado el procesamiento de la pulsación de tecla, la pulsación se asigna al control con el foco. Por ejemplo, si la propiedad KeyPreview está establecida en verdadero y el control seleccionado actualmente es un TextBox, después de que la pulsación de tecla sea manejada por los manejadores de eventos del formulario, el control TextBox recibirá la clave que se presionó. Para gestionar eventos de teclado solo en el nivel de formulario y no permitir que los controles reciban eventos de teclado, establezca la propiedad KeyPressEventArgs.Handled en el controlador de eventos de KeyPress de su formulario en verdadero.

Puede usar esta propiedad para procesar la mayoría de las pulsaciones de teclas en su aplicación y manejar la combinación de teclas o llamar al control apropiado para manejar la pulsación de tecla. Por ejemplo, cuando una aplicación utiliza teclas de función, es posible que desee procesar las pulsaciones de teclas en el nivel de formulario en lugar de escribir código para cada control que pueda recibir eventos de pulsación de teclas.

Básicamente, cuando lo configura en verdadero, su formulario puede procesar eventos clave así como también sus controles.

El usuario de EG presiona la tecla K, se llama a los manejadores de eventos de formularios (tecla abajo, tecla arriba, tecla presionada) y luego se llama a los manejadores de eventos en el control actualmente activo.

EDITAR : No, no hay inconvenientes ni sorpresas desagradables. Lo único que se me ocurre es una disminución muy pequeña en el rendimiento, ya que necesita verificar los identificadores de eventos en el formulario para cada KeyDown, KeyUp, KeyPressed. Aparte de eso, a menos que agregue controladores de eventos al formulario y haga algo que pueda causar problemas. estás perfectamente bien. Si no necesita gestionar globalmente los eventos clave excepto en los controles, le sugiero que deje esto como falso para evitar los controles adicionales. En las PC modernas esto no tendría una diferencia visible.

El modelo estándar de eventos de Windows es que la ventana con el foco del teclado obtiene todos los eventos del teclado. Recuerde que en Windows, todo es una ventana: un “control” es solo una ventana que es hija de otra ventana. Depende de esa ventana disparar mensajes a su padre si elige hacerlo, cuando se presionan ciertas teclas.

Para estandarizar la navegación entre controles en un cuadro de diálogo, Windows también proporciona el ‘administrador de diálogo’. En el código nativo, para los diálogos modales esto es manejado por el bucle de mensaje modal dentro de la función DialogBox . Para los cuadros de diálogo no modal, debe llamar a IsDialogMessage dentro de su propio bucle de mensajes. Así es como roba la Pestaña y las teclas del cursor para navegar entre los controles, y Enter para presionar el botón predeterminado. Esto tiene el efecto opuesto de no permitir que los controles manejen Intro de forma predeterminada, que los controles de edición multilínea manejarían normalmente. Para descubrir si un control desea manejar una clave, el código del administrador de diálogo envía al control enfocado un mensaje WM_GETDLGCODE ; si el control responde de forma adecuada, el administrador de diálogo devuelve FALSE permite a DispatchMessage entregarlo realmente en el procedimiento de ventana, de lo contrario, el administrador de diálogo hace lo suyo.

Windows Forms simplemente completa los antiguos controles nativos, por lo que debe ajustarse al modelo de eventos de Win32. Implementa el mismo enfoque de administrador de diálogo, por lo que no permite, por defecto, ver las teclas Tab, Retorno y cursor.

El enfoque recomendado, si desea manejar una de esas claves, es anular PreviewKeyDown y establecer la propiedad PreviewKeyDownEventArgs IsInputKey en true .