.net - tutorial - Desventaja de configurar Form.KeyPreview=true?
windows forms visual studio 2017 (3)
Desde msdn.microsoft.com/en-us/library/…
Cuando esta propiedad se establece en verdadero, el formulario recibirá todos los eventos KeyPress, KeyDown y KeyUp. Después de que los controladores de eventos del formulario hayan completado el procesamiento de la pulsación de tecla, la pulsación de tecla se asigna al control con el foco. Por ejemplo, si la propiedad KeyPreview se establece en true y el control seleccionado actualmente es un TextBox, después de que la pulsación de las teclas sea manejada por los controladores de eventos del formulario, el control TextBox recibirá la tecla que se presionó. Para manejar 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 tecla en su aplicación y manejar la pulsación de tecla 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 tecla en el nivel de formulario en lugar de escribir código para cada control que pueda recibir eventos de pulsación de tecla.
Básicamente, cuando lo establece en verdadero, su formulario puede procesar eventos clave, así como sus controles.
EG El usuario presiona la tecla K, se llaman los controladores de eventos de formularios (Key Down, Key Up, Key Pressed) y luego se llaman los controladores de eventos en el control activo actual.
EDITAR : No, no hay desventajas o sorpresas desagradables. Lo único en lo que puedo pensar es en una disminución muy pequeña del rendimiento, ya que necesita verificar los controladores de eventos en el formulario para cada KeyDown, KeyUp, KeyPressed. Aparte de eso, a menos que esté agregando controladores de eventos al formulario y haciendo algo que pueda causar problemas. estas perfectamente bien Si no necesita manejar eventos clave de forma global, excepto en los controles, le sugiero que deje esto como falso para evitar las comprobaciones adicionales. En las PC modernas, esto no tendría una diferencia visible.
Me pregunto para qué sirve la propiedad Form.KeyPreview. ¿Por qué existe y qué "arriesgo" al establecerlo en verdadero? Supongo que debe tener algún efecto negativo; de lo contrario, ¿no debería existir (o al menos ser cierto de forma predeterminada)?
EDIT : Sé perfectamente bien lo que hace. Estoy preguntando por qué . ¿Por qué tengo que configurarlo en verdadero para que se activen los eventos del teclado? ¿Por qué los eventos del teclado no siempre se disparan para un formulario? ¿Qué no es solo que 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 todas las otras formas heredan. ¿Me llevaría una sorpresa desagradable?
El modelo estándar de eventos de Windows es que la ventana con el enfoque 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 sus padres si así lo decide, cuando se presionan ciertas teclas.
Para estandarizar la navegación entre los controles de un cuadro de diálogo, Windows también proporciona el "administrador de diálogo". En el código nativo, para los cuadros de diálogo modales, esto se maneja mediante el bucle de mensaje modal dentro de la función DialogBox
. Para los diálogos sin modelo, debe llamar a IsDialogMessage
dentro de su propio bucle de mensajes. Así es como roba las teclas Tab y 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 Enter de forma predeterminada, que los controles de edición multilínea normalmente manejarían. Para descubrir si un control quiere manejar una clave, el código del administrador de diálogo envía al control enfocado un mensaje WM_GETDLGCODE
; si el control responde adecuadamente, el administrador de diálogo devuelve FALSE
permitiendo que DispatchMessage
realmente lo entregue al procedimiento de la ventana, de lo contrario, el administrador de diálogo hace lo suyo.
Windows Forms en gran medida simplemente envuelve los antiguos controles nativos, por lo que tiene que ajustarse al modelo de eventos de Win32. Implementa el mismo enfoque de administrador de diálogo, por lo que, por defecto, no le permite ver las teclas Tab, Retorno y las teclas de cursor.
El método recomendado, si desea manejar una de esas claves, es anular PreviewKeyDown
y establecer la propiedad PreviewKeyDownEventArgs
IsInputKey
en true
.
Form.KeyPreview
es un poco de anacronismo, heredado del modelo de objetos de Visual Basic para el diseño de formularios. En los días de VB6, necesitaba KeyPreview
para poder implementar pulsaciones de teclas abreviadas. Eso ya no es necesario en Windows Forms, anular la 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 programadores de VB6 a cambiar de .NET a principios de la década de 2000. El punto de KeyPreview
o ProcessCmdKey()
es permitir que su interfaz de usuario responda a las teclas de acceso directo. Los mensajes de teclado normalmente se envían al control que tiene el foco. El bucle de mensajes de Windows Forms le permite al código echar un vistazo a ese mensaje antes de que el control lo vea. Eso es importante para las teclas de atajo, ya que la implementación del evento KeyDown
para cada control que pueda obtener el foco para detectarlas es muy poco práctico.
Establecer KeyPreview
en True no causa problemas. El evento KeyDown
del KeyDown
se ejecutará, 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 pulsaciones que se utilizan para la navegación. Al igual que las teclas de cursor y Tab
, Escape
y Enter
para un diálogo. No es un problema con ProcessCmdKey()
.