WPF: OnKeyDown () ne pas être appelé à la barre d'espace dans le contrôle dérivé de WPF TextBox

StackOverflow https://stackoverflow.com/questions/1458748

  •  12-09-2019
  •  | 
  •  

Question

Dans une application WPF, j'ai un contrôle que je dérivé de TextBox comme ceci:

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

La méthode OnKeyDown est pas appelée en entrant dans un espace dans la zone de texte, ni lors de la frappe de retour arrière, mais ne se déclenche pour une autre entrée comprenant des caractères imprimables normaux (par exemple « a ») et les touches de modification (par exemple).

J'utilise ce contrôle avec jeu IsReadOnly true pour que je puisse afficher le texte sélectionnable, non modifiable. Le contrôle utilisé dans le DataGrid de WPFToolkit, et je veux des événements KeyDown pour propager la grille de données, même si le SelectableTextBlock a le focus, ce qui est la raison pour laquelle je me sers d'un contrôle personnalisé pour marquer explicitement l'événement comme non prise en charge.

Le problème est que l'événement est même pas fait à mon contrôle pour certaines touches. Je ne peux pas utiliser OnPreviewKeyDown dans le DataGrid pour contourner cela, car je ne veux d'autres contrôles utilisés dans la grille de données à avaler l'espace KeyDown événement.

Quelqu'un sait comment je peux obtenir l'événement KeyDown pour la touche espace pour se propager jusqu'à?

Merci.

Était-ce utile?

La solution 2

Il semble que le problème est que l'espace (et backspace, etc.) événement clé vers le bas est en cours de traitement déjà dans la zone de texte, avant qu'il bouillonne à mon contrôle dérivé. Je suppose que dans le cadre du processus de composition de texte, comme Wim affiché.

Pour contourner ce problème, je l'ai ajouté un gestionnaire qui recevra l'événement clé vers le bas même il a déjà été traitée, et définit ses membres Handled faux, afin de lui permettre de réaliser le bouillonnement normalement. Dans l'exemple ci-dessous, il fait exactement ce pour les clés de l'espace, mais dans mon cas, je vais devoir faire le faire pour tous les événements clés que je vraiment ne veux pas dans mon SelectedableTextBlock traitées, comme je ne savent pas quels événements clés les parents pourraient être intéressés encore.

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

Je suis bien sûr toujours intéressé si quelqu'un a une meilleure solution ...

Merci, E.

Autres conseils

L'événement PreviewKeyDown existe exactement pour ce genre de chose.

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

Votre gestionnaire KeyDown ne recevra jamais l'événement KeyDown pour la barre d'espace.

J'ai eu ce problème avec des espaces et des événements une fois dans une zone de texte. Pour les événements ne se déclenchent pas seulement lorsque vous ajoutez ou supprimez un espace?

est ce que je suis comme une réponse: ( http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b )

Parce que certains IMEs traiteront des espaces de frappe dans le cadre du processus de composition de texte, c'est pourquoi il mange par Avalon signaler texte composited correcte par événement TextInput.

Je pourrais être complètement hors de la portée, mais la lecture de ce fil emmideatly m'a fait penser à cette question que j'avais une fois.

Cordialement, Wim

Derive mot à dire, RestrictKeysTextBox de TextBox.

public class RestrictKeysTextBox : TextBox
{
    ....
}

Remplacer l'événement OnPreviewKeyDown dans le RestrictKeysTextBox.

logique de mettre dans cette override comme ceci:

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

Liez l'instance du RestrictKeysTextBox à votre DataGrid.

Cela devrait fonctionner sans déroger à OnPreviewKeyDown dans le DataGrid et d'éliminer les problèmes associés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top