2009-09-22 7 views
15

In un'applicazione WPF, ho un controllo che ho derivato da TextBox simili:WPF: OnKeyDown() non venga richiamato per la chiave spazio nel controllo derivato da WPF TextBox

public class SelectableTextBlock : TextBox 
{ 
    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     base.OnKeyDown(e); 
     e.Handled = false; 
    } 
} 

Procedimento OnKeyDown non è chiamato quando si immette uno spazio nel TextBox, né quando si colpisce Backspace, ma si attiva per altri input inclusi normali caratteri stampabili (ad esempio 'a') e tasti modificatori (ad esempio).

Sto usando questo controllo con IsReadOnly impostato su true in modo da poter visualizzare testo selezionabile e non modificabile. Il controllo utilizzato in DataGrid di WPFToolkit, e voglio che gli eventi KeyDown si propaghino sulla griglia di dati, anche se il SelectableTextBlock è focalizzato, motivo per cui sto usando un controllo personalizzato per contrassegnare esplicitamente l'evento come non gestito.

Il problema è che l'evento non riesce nemmeno a controllarlo per determinati tasti. Non posso semplicemente utilizzare OnPreviewKeyDown nel DataGrid per aggirare questo, dal momento che voglio altri controlli utilizzati nella griglia di dati per ingoiare lo spazio KeyDown evento.

Qualcuno sa come posso far propagare l'evento KeyDown per lo Space Key?

Grazie.

risposta

12

sembra che il problema è che lo spazio (e backspace ecc) DOWN evento viene gestito già all'interno della TextBox, prima che bolle fino al mio controllo derivato. Presumo come parte del processo di composizione del testo, come Wim ha pubblicato.

Per risolvere il problema, ho aggiunto un gestore che riceverà l'evento di abbassamento della chiave anche se è già stato gestito e imposta il suo membro gestito su falso, per consentirgli di continuare a girare normalmente. Nell'esempio seguente lo fa solo per le chiavi dello spazio, ma nel mio caso dovrò farlo per qualsiasi evento chiave che io, , non voglio veramente gestire nel mio SelectedableTextBlock, perché non so cosa eventi chiave a cui potrebbero interessare i genitori.

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; 
     } 
    } 
    ... 
} 

sono ovviamente ancora interessato se qualcuno ha una soluzione migliore ...

Grazie, E.

2

Ho avuto questo problema con spazi ed eventi una volta in una casella di testo. Gli eventi NON sono attivati ​​solo quando aggiungi o rimuovi uno spazio?

Questo è quello che ho ottenuto come risposta: (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b)

Poiché alcuni IME tratteranno battitura spazio bianco come parte del processo di composizione del testo, è per questo che mangia da Avalon segnalare il corretto il testo mescolati attraverso TextInput evento.

Potrei essere completamente fuori dal campo di applicazione ma leggere questo thread mi ha fatto pensare emmideat di quel problema che avevo una volta.

Cordiali saluti, Wim

+0

Grazie per la risposta, Wim. Questo sembra un problema correlato. Ho scoperto che l'evento non è attivato per i caratteri spazio e il backspace e cancella la pressione dei tasti. Mentre nel tuo caso cercavi di fermare la pressione del tasto spazio gestita dalla casella di testo e lo facevo gestendo l'anteprima, sto tentando di far scoppiare l'evento ai controlli padre, quindi questo non funzionerebbe per me . Ho una soluzione alternativa che gestisce gli eventi di key down gestiti e li imposta a gestire. Pubblicherò il codice per l'interesse generale in una risposta alla mia domanda originale. Pensi ancora che ci debba essere un modo migliore. Grazie, E. – Ergwun

+0

Che avrebbe dovuto leggere: "Ho una soluzione alternativa che gestisce gli eventi chiave in giù e li imposta su * non gestito *." – Ergwun

2

derivare un esempio, RestrictKeysTextBox da TextBox.

public class RestrictKeysTextBox : TextBox 
{ 
    .... 
} 

Sovrascrivere l'evento OnPreviewKeyDown in RestrictKeysTextBox.

logica messo in questa esclusione come questa:

if (e.Key == Key.Space) 
{ 
    e.Handled = true; 
} 

Bind l'istanza del RestrictKeysTextBox al DataGrid.

Questo dovrebbe funzionare senza eseguire l'override di OnPreviewKeyDown in DataGrid ed eliminare i problemi associati.

14

L'evento PreviewKeyDown esiste esattamente per questo genere di cose.

private void spacebarHandler_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Space) 
     e.Handled = true; 
} 

Il tuo gestore KeyDown non riceverà mai l'evento KeyDown per barra spaziatrice.

+1

Non funziona per me in .NET 4.5 – Logan

+2

Funziona per me in .Net 4.6.1 – Dabblernl