Svantaggi dell’impostazione di Form.KeyPreview = true?

Mi chiedo a cosa sia effettivamente utile la proprietà Form.KeyPreview? Perché esiste e cosa “rischio” impostandolo su vero? Immagino che debba avere qualche effetto negativo – altrimenti non dovrebbe esistere affatto (o almeno essere vero per impostazione predefinita)?

EDIT : So perfettamente quello che fa. Sto chiedendo perché Perché devo impostarlo su true per triggersre gli eventi della tastiera? Perché gli eventi della tastiera non si triggersno sempre per un modulo. Cosa non è solo il comportamento standard?

La ragione particolare che chiedo è: ho appena impostato KeyPreview = true nel modulo base della mia app, da cui ereditano tutte le altre forms. Sono in qualche brutta sorpresa?

Form.KeyPreview è un po ‘anacronistico, ereditato dal modello di oggetti di Visual Basic per la progettazione di moduli. Tornando in VB6 giorni, era necessario KeyPreview per essere in grado di implementare sequenze di tasti di scelta rapida. Non è più necessario in Windows Form, ignorando ProcessCmdKey() è la soluzione migliore:

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

Ma KeyPreview stato supportato per aiutare la legione di programmatori VB6 a tornare su .NET nei primi anni 2000. Il punto di KeyPreview o ProcessCmdKey() è di consentire all’interfaccia utente di rispondere ai tasti di scelta rapida. I messaggi della tastiera vengono normalmente inviati al controllo che ha lo stato attivo. Il ciclo di messaggi di Windows Form consente al codice di dare un’occhiata a quel messaggio prima che il controllo lo veda. Questo è importante per i tasti di scelta rapida, l’implementazione dell’evento KeyDown per ogni controllo che potrebbe essere messo a fuoco per rilevarli è molto poco pratico.

L’impostazione di KeyPreview su True non causa problemi. L’evento KeyDown della KeyDown verrà eseguito, avrà effetto solo se ha codice che fa qualcosa con la sequenza di tasti. Ma attenzione che segue da vicino l’utilizzo di VB6, non è ansible vedere il tipo di sequenze di tasti utilizzate per la navigazione. Come i tasti cursore e Tab , Escape e Enter per una finestra di dialogo. Non è un problema con ProcessCmdKey() .

Da MSDN

Quando questa proprietà è impostata su true, il modulo riceverà tutti gli eventi KeyPress, KeyDown e KeyUp. Dopo che i gestori di eventi del modulo hanno completato l’elaborazione della sequenza di tasti, la sequenza di tasti viene quindi assegnata al controllo con focus. Ad esempio, se la proprietà KeyPreview è impostata su true e il controllo attualmente selezionato è un controllo TextBox, dopo che il tasto è stato gestito dai gestori di eventi del modulo, il controllo TextBox riceverà la chiave che è stata premuta. Per gestire gli eventi di tastiera solo a livello di modulo e non consentire ai controlli di ricevere eventi di tastiera, impostare la proprietà KeyPressEventArgs.Handled nel gestore di eventi KeyPress del modulo su true.

È ansible utilizzare questa proprietà per elaborare la maggior parte delle sequenze di tasti nell’applicazione e gestire la sequenza di tasti o chiamare il controllo appropriato per gestire la sequenza di tasti. Ad esempio, quando un’applicazione utilizza i tasti di funzione, è ansible che si desideri elaborare le sequenze di tasti a livello di modulo piuttosto che scrivere il codice per ogni controllo che potrebbe ricevere eventi di sequenza di tasti.

Fondamentalmente quando lo hai impostato su true, il tuo modulo può elaborare eventi chiave oltre ai tuoi controlli.

EG L’utente preme il tasto K, i gestori di eventi dei form vengono richiamati (Key Down, Key Up, Key Pressed) e quindi vengono chiamati i gestori di eventi sul controllo attualmente attivo.

EDIT : No non ci sono svantaggi o brutte sorprese. L’unica cosa che posso pensare è una riduzione delle prestazioni molto piccola in quanto è necessario controllare gli handle di evento sul modulo per ogni KeyDown, KeyUp, KeyPressed. A parte questo, a meno che tu non aggiunga gestori di eventi al modulo e faccia qualcosa che potrebbe causare problemi. stai perfettamente bene. Se non è necessario gestire globalmente eventi chiave, ad eccezione dei controlli, suggerirei di lasciare questo come falso per evitare i controlli extra. Su PC moderni questo non avrebbe una differenza visibile.

Il modello di eventi standard di Windows è che la finestra con lo stato attivo della tastiera ottiene tutti gli eventi della tastiera. Ricorda che in Windows, tutto è una finestra: un “controllo” è solo una finestra figlia di un’altra finestra. Spetta a quella finestra triggersre i messaggi sul suo genitore se sceglie di farlo, quando vengono premuti determinati tasti.

Per standardizzare la navigazione tra i controlli in una finestra di dialogo, Windows fornisce anche il “gestore di windows di dialogo”. Nel codice nativo, per le windows di dialogo modali questo viene gestito dal ciclo dei messaggi modali all’interno della funzione DialogBox . Per le windows di dialogo non modali, è necessario chiamare IsDialogMessage all’interno del proprio loop di messaggi. Ecco come ruba i tasti Tab e cursore per navigare tra i controlli, e Invio per premere il pulsante predefinito. Ciò ha l’effetto opposto di non consentire ai controlli di gestire Invio per impostazione predefinita, che normalmente i controlli di modifica su più righe dovrebbero gestire. Per scoprire se un controllo vuole gestire una chiave, il codice gestore di windows di dialogo invia al controllo focalizzato un messaggio WM_GETDLGCODE ; se il controllo risponde in modo appropriato, il gestore di windows di dialogo restituisce FALSE consentendo a DispatchMessage di consegnarlo effettivamente alla procedura della finestra, altrimenti il ​​gestore di windows di dialogo fa la sua stessa cosa.

Windows Form in gran parte semplicemente avvolge i vecchi controlli nativi, quindi deve essere conforms al modello di eventi di Win32. Implementa lo stesso approccio di gestore di windows di dialogo – quindi perché non consente, di default, di visualizzare Tab, Return e i tasti cursore.

L’approccio consigliato, se si desidera gestire una di queste chiavi, è sovrascrivere PreviewKeyDown e impostare la proprietà PreviewKeyDownEventArgs IsInputKey su true .