c# - WPF: OnKeyDown() no se llama para la clave de espacio en el control derivado de TextBox de WPF
(4)
Derive a say, RestrictKeysTextBox de TextBox.
public class RestrictKeysTextBox : TextBox
{
....
}
Reemplace el evento OnPreviewKeyDown en RestrictKeysTextBox.
Ponga la lógica en esta anulación de esta manera:
if (e.Key == Key.Space)
{
e.Handled = true;
}
Enlace la instancia de RestrictKeysTextBox a su DataGrid.
Eso debería funcionar sin anular el OnPreviewKeyDown en el DataGrid y eliminar los problemas asociados.
En una aplicación WPF, tengo un control que he derivado de TextBox como este:
public class SelectableTextBlock : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
e.Handled = false;
}
}
El método OnKeyDown no se llama cuando se ingresa un espacio en TextBox, ni cuando se pulsa Retroceso, pero se dispara para otra entrada que incluye caracteres imprimibles normales (por ejemplo, "a") y teclas modificadoras (por ejemplo).
Estoy usando este control con IsReadOnly establecido en verdadero para poder mostrar texto seleccionable y no editable. El control usado en el DataGrid de WPFToolkit, y quiero que los eventos KeyDown se propaguen hacia arriba en la cuadrícula de datos, incluso si el SelectableTextBlock tiene un enfoque, por lo que estoy usando un control personalizado para marcar explícitamente el evento como no manejado.
El problema es que el evento ni siquiera está a mi alcance para ciertas claves. No puedo usar OnPreviewKeyDown en el DataGrid para solucionar esto, ya que quiero que se usen otros controles en la cuadrícula de datos para tragar el evento KeyDown de espacio.
¿Alguien sabe cómo puedo obtener el evento KeyDown para que la clave de espacio se propague?
Gracias.
El evento PreviewKeyDown existe exactamente para este tipo de cosas.
private void spacebarHandler_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
e.Handled = true;
}
Su controlador KeyDown nunca recibirá el evento KeyDown para la barra espaciadora.
Parece que el problema es que el evento de desactivación de la tecla de espacio (y retroceso, etc.) ya se está manejando dentro del TextBox, antes de que se incorpore a mi control derivado. Asumo como parte del proceso de composición del texto, como publicó Wim.
Para solucionar esto, agregué un controlador que recibirá el evento de desactivación de clave, incluso cuando ya se ha manejado, y establece su miembro manejado en falso, para permitir que continúe burbujeando normalmente. En el siguiente ejemplo, solo hace esto con las teclas de espacio, pero en mi caso necesitaré hacerlo para cualquier evento clave que realmente no quiero que se maneje en mi SelectedableTextBlock, ya que no sé qué eventos clave Los padres pueden estar interesados en todavía.
public class SelectableTextBlock : TextBox
{
public SelectableTextBlock() : base()
{
this.AddHandler(SelectableTextBlock.KeyDownEvent, new RoutedEventHandler(HandleHandledKeyDown), true);
}
public void HandleHandledKeyDown(object sender, RoutedEventArgs e)
{
KeyEventArgs ke = e as KeyEventArgs;
if (ke.Key == Key.Space)
{
ke.Handled = false;
}
}
...
}
Por supuesto, todavía estoy interesado si alguien tiene una mejor solución ...
Gracias, e.
Tuve este problema con espacios y eventos una vez en un cuadro de texto. ¿Los eventos NO se activan solo cuando agrega o elimina un carácter de espacio?
Esto es lo que obtuve como respuesta: ( http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b )
Debido a que algunos IME tratarán las pulsaciones de espacio en blanco como parte del proceso de composición del texto, es por eso que Avalon se encarga de informar el texto compuesto correcto a través del evento TextInput.
Podía estar completamente fuera del alcance, pero al leer este hilo, me hizo pensar en el problema que una vez tuve.
Saludos cordiales, Wim