55 votes

Exécution de la commande viewmodels lors de l'entrée dans un TextBox

Je veux exécuter une commande dans mon viewmodel lorsque l'utilisateur appuie sur la touche Entrée d'un champ de texte. La commande fonctionne lorsqu'elle est liée à un bouton.

<Button Content="Add" Command="{Binding Path=AddCommand}" />

Mais je n'arrive pas à le faire fonctionner à partir de la TextBox. J'ai essayé un Inputbinding, mais ça n'a pas marché.

<TextBox.InputBindings>
    <KeyBinding Command="{Binding Path=AddCommand}" Key="Enter"/>
</TextBox.InputBindings>

J'ai également essayé de définir le bouton de travail par défaut, mais il n'est pas exécuté lorsque l'on appuie sur la touche Entrée.

Merci pour votre aide.

149voto

mkamioner Points 385

Je sais que je suis en retard pour la fête, mais j'ai réussi à faire fonctionner ceci pour moi. Essayez d'utiliser Key="Return" au lieu de Key="Enter"

Voici l'exemple complet

<TextBox Text="{Binding FieldThatIAmBindingToo, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Command="{Binding AddCommand}" Key="Return" />
    </TextBox.InputBindings>
</TextBox>

Veillez à utiliser UpdateSourceTrigger=PropertyChanged dans votre liaison, sinon la propriété ne sera pas mise à jour jusqu'à ce que le focus soit perdu, et appuyer sur entrée ne perdra pas le focus...

J'espère que cela a été utile !

13voto

Andreas Zita Points 1622

Vous n'avez probablement pas fait de la commande une propriété, mais un champ. Cela ne fonctionne que pour lier des propriétés. Changez votre AddCommand en une propriété et cela fonctionnera. (Votre XAML fonctionne bien pour moi avec une propriété au lieu d'un champ pour la commande -> pas besoin de code derrière).

5voto

Mark Heath Points 22240

Voici une propriété de dépendance jointe que j'ai créée pour cela. Elle a l'avantage de garantir que votre liaison de texte est mise à jour vers le ViewModel avant que la commande ne se déclenche (utile pour Silverlight qui ne supporte pas le déclencheur de mise à jour de la source de la propriété modifiée).

public static class EnterKeyHelpers
{
    public static ICommand GetEnterKeyCommand(DependencyObject target)
    {
        return (ICommand)target.GetValue(EnterKeyCommandProperty);
    }

    public static void SetEnterKeyCommand(DependencyObject target, ICommand value)
    {
        target.SetValue(EnterKeyCommandProperty, value);
    }

    public static readonly DependencyProperty EnterKeyCommandProperty =
        DependencyProperty.RegisterAttached(
            "EnterKeyCommand",
            typeof(ICommand),
            typeof(EnterKeyHelpers),
            new PropertyMetadata(null, OnEnterKeyCommandChanged));

    static void OnEnterKeyCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        ICommand command = (ICommand)e.NewValue;
        FrameworkElement fe = (FrameworkElement)target;
        Control control = (Control)target;
        control.KeyDown += (s, args) =>
        {
            if (args.Key == Key.Enter)
            {
                // make sure the textbox binding updates its source first
                BindingExpression b = control.GetBindingExpression(TextBox.TextProperty);
                if (b != null)
                {
                    b.UpdateSource();
                }
                command.Execute(null);
            }
        };
    }
}

Vous l'utilisez comme ça :

<TextBox 
    Text="{Binding Answer, Mode=TwoWay}" 
    my:EnterKeyHelpers.EnterKeyCommand="{Binding SubmitAnswerCommand}"/>

1voto

Jay Points 27907

Voici une approche, si vous êtes prêt à utiliser un peu de code derrière :

Dans le XAML, liez la commande et souscrivez à l'événement KeyDown.

  <TextBox app:Window1.TextBoxPressEnterCommand="{Binding AddCommand}" 
      KeyDown="TextBox_KeyDown" />

Dans le codebehind, traitez l'événement KeyDown en vérifiant la présence d'Enter et en exécutant la commande liée à la TextBox. Grâce à la propriété de dépendance jointe, vous pouvez lier différentes textboxes à différentes commandes ICommand objets.

public partial class Window1 : Window
{
    public Window1() { InitializeComponent(); }

      // event handler for KeyDown event
    private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
            // if user didn't press Enter, do nothing
        if (!e.Key.Equals(Key.Enter)) return;

            // execute the command, if it exists
            var cmd = GetTextBoxPressEnterCommand((TextBox) sender);
            if(cmd != null) cmd.Execute(null);
    }

      // declare an attached dependency property
    public static ICommand GetTextBoxPressEnterCommand(TextBox obj)
    {
        return (ICommand)obj.GetValue(TextBoxPressEnterCommandProperty);
    }
    public static void SetTextBoxPressEnterCommand(TextBox obj, ICommand value)
    {
        obj.SetValue(TextBoxPressEnterCommandProperty, value);
    }
    public static readonly DependencyProperty TextBoxPressEnterCommandProperty =
        DependencyProperty.RegisterAttached("TextBoxPressEnterCommand", typeof(ICommand), typeof(Window1));

}

-3voto

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