web-dev-qa-db-fra.com

WPF: une zone de texte qui a un événement qui se déclenche lorsque vous appuyez sur la touche Entrée

Au lieu d'attacher un événement PreviewKeyUp à chaque TextBox de mon application et de vérifier si la touche enfoncée était une touche Entrée, puis d'effectuer une action, j'ai décidé d'implémenter la version étendue d'une TextBox qui inclut un événement DefaultAction qui se déclenche lorsqu'une touche Entrée est enfoncée dans une TextBox

Ce que j'ai fait était essentiellement de créer une nouvelle classe qui s'étend de TextBox avec un événement public DefaultAction, tel que:

public class DefaultTextBoxControl:TextBox
{
    public event EventHandler<EventArgs> DefaultAction = delegate { };

    public DefaultTextBoxControl()
    {
        PreviewKeyUp += DefaultTextBoxControl_PreviewKeyUp;
    }

    void DefaultTextBoxControl_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key != Key.Enter)
        {
            return;
        }
        DefaultAction(this, EventArgs.Empty);
    }
}

J'utilise ensuite cette zone de texte personnalisée à partir de mon application comme telle (xaml):

<Controls:DefaultTextBoxControl  DefaultAction="DefaultTextBoxControl_DefaultAction">
</Controls:DefaultTextBoxControl>

Maintenant, dans ma petite expérience d’apprentissage de WPF, j’ai réalisé que la plupart du temps, il existe un moyen plus "cool" (et, espérons-le, plus facile) de mettre en œuvre les choses.

... donc ma question est, Comment puis-je améliorer le contrôle ci-dessus? Ou peut-être y a-t-il un autre moyen de faire le contrôle ci-dessus? ... peut-être en n'utilisant que du code déclaratif au lieu des deux types déclaratif (xaml) et procédural (C #)?

17
Andreas Grech

Jetez un coup d'œil à cet article de blog depuis quelques mois à l’origine, j’attache un gestionnaire d’événements «global» à TextBox.GotFocus pour sélectionner le texte. 

Pour l'essentiel, vous pouvez gérer l'événement KeyUp dans votre classe App, comme suit:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.KeyUpEvent,
        new System.Windows.Input.KeyEventHandler(TextBox_KeyUp));

    base.OnStartup(e);
}

private void TextBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key != System.Windows.Input.Key.Enter) return;

    // your event handler here
    e.Handled = true;
    MessageBox.Show("Enter pressed");
}

... et maintenant chaque TextBox de votre application appellera la méthode TextBox_KeyUp au fur et à mesure que les utilisateurs le tapent.

Mettre à jour

Comme vous l'avez souligné dans votre commentaire, cela n'est utile que si chaque TextBox doit exécuter le même code.

Pour ajouter un événement arbitraire tel qu'une pression sur la touche Entrée, il vaut peut-être mieux regarder dans Evénements attachés . Je crois que cela peut vous donner ce que vous voulez.

31
Matt Hamilton

Depuis que cette question a été posée, il existe maintenant une propriété InputBindings sur les TextBox et autres contrôles. Avec cela, une solution purement XAML peut être utilisée, plutôt que d'utiliser des contrôles personnalisés. Assigner KeyBindings pour Return et Enter pour pointer sur une commande peut le faire.

Exemple:

<TextBox Text="Test">
    <TextBox.InputBindings>
        <KeyBinding Command="{Binding SomeCommand}" Key="Return" />
        <KeyBinding Command="{Binding SomeCommand}" Key="Enter" />
    </TextBox.InputBindings>
</TextBox>

Certains ont mentionné que Enter ne fonctionnait pas toujours et que Return pouvait être utilisé sur certains systèmes.

19
Cyral

Lorsque l'utilisateur appuie sur la touche Entrée dans la zone de texte, l'entrée dans la zone de texte apparaît dans une autre zone de l'interface utilisateur.

Le XAML suivant crée l'interface utilisateur, qui consiste en un StackPanel, un TextBlock et un TextBox.

<StackPanel>
  <TextBlock Width="300" Height="20">
    Type some text into the TextBox and press the Enter key.
  </TextBlock>
  <TextBox Width="300" Height="30" Name="textBox1"
           KeyDown="OnKeyDownHandler"/>
  <TextBlock Width="300" Height="100" Name="textBlock1"/>
</StackPanel>

Le code suivant derrière crée le gestionnaire d'événements KeyDown. Si la touche sur laquelle vous appuyez est la touche Entrée, un message s'affiche dans le TextBlock.

private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        textBlock1.Text = "You Entered: " + textBox1.Text;
    }
}

Pour plus d'informations, lisez MSDN Doc.

1
Ali Asad