12 votes

Application WPF large capture des événements de touche haut/bas

Je cherche à capturer les événements de frappe n'importe où dans mon application WPF, peu importe quel élément UI a le focus. Actuellement, je n'ai pas de chance. Est-ce que quelqu'un peut suggérer des stratégies que je n'aurais peut-être pas essayées ? Ou, idéalement, fournir une réponse du type "oh c'est facile, il suffit de faire ceci".

C'est une application distribuée, qui a un système de chat. L'effet que je recherche est que l'utilisateur puisse commencer à taper un message de chat à tout moment, sans passer à une boîte de chat standard. J'afficherai leur message dans l'application moi-même, en utilisant des objets FormattedText. C'est important car cela signifie qu'il n'y a pas d'éléments d'entrée de texte dans l'application.

Ma structure XAML ressemble à peu près à :

J'ajoute programmable des éléments dans Canvas 2, et manipule Image 2, c'est pourquoi il a cette structure.

J'ai essayé d'ajouter les événements KeyDown, KeyUp et Preview à MainWindow et Canvas 1, mais aucun d'entre eux ne semble se déclencher (je vérifie avec des points d'arrêt). J'ai également, après avoir lu une autre question connexe ici, essayé de définir manuellement le focus sur la fenêtre principale dans la méthode Loaded().

Je sais qu'il y a de nombreuses questions connexes sur ce site, mais elles ne m'ont pas aidé car :

  • il n'y a pas de réponses (ma question sera-t-elle répondue ?)
  • elles supposent un widget d'entrée de texte et s'intéressent à la remontée des événements
  • elles veulent un raccourci clavier pour un petit nombre de touches - je voudrais capturer n'importe quelle touche
  • elles s'intéressent à la détection si une touche de contrôle/majuscule/alt est enfoncée après avoir déjà capturé l'événement

Merci d'avoir pris le temps de lire mon post long et merci pour les suggestions.

Mise à jour (Après le commentaire de Rachel) Lorsque je mets un TextBox et définis le focus sur le TextBox, une méthode d'événement de touche au niveau de la MainWindow se déclenchera. Donc ça fonctionne comme annoncé.

Cependant, j'aimerais vraiment ne pas avoir de widget d'entrée de texte explicite dans l'application. J'aimerais que l'utilisateur puisse simplement commencer à taper pour composer un message.

10voto

WernerCD Points 564

Un peu de bricolage m'a donné ceci :

XAML :

CS :

using System.Windows;
using System.Windows.Input;

namespace KeyInput
{
    /// 
    /// Logique d'interaction pour MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.KeyDown += new KeyEventHandler(OnButtonKeyDown);
        }

        private void OnButtonKeyDown(object sender, KeyEventArgs e)
        {
            test.Content = test.Content + e.Key.ToString();
        }
    }
}

Ceci imprime des choses comme "Shift" donc vous devriez évidemment utiliser des switches... mais il a une zone de texte qui recueille les presses de touches.

4voto

cursa Points 397

J'ai réussi à résoudre le problème, inspiré par les réponses de Rachel et WernerCD. Comme ils l'ont tous les deux démontré, avoir la capture d'événements au niveau de la fenêtre principale fonctionne. Le problème était que j'ai omis de mentionner que j'avais une boîte de dialogue avant le chargement de la fenêtre principale, ce qui semble interférer avec la mise au point normale du clavier sur la fenêtre principale. Mettre explicitement Keyboard.focus() dans la méthode Loaded() est trop tôt. J'ai résolu le problème en mettant Keyboard.focus() dans la méthode MainWindow_ContentRendered().

Tout va bien maintenant (jusqu'au prochain problème de toute façon). Merci pour l'aide.

2voto

Rachel Points 49408

Je rajoute généralement un événement PreviewKeyDown à la MainWindow.

Peut-être que votre problème est que vous n'avez aucun contrôle qui accepte le focus clavier sur votre application. Obtenez-vous les mêmes résultats si vous ajoutez une zone de texte (TextBox) à la MainWindow et que vous définissez le focus là?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X