2009-10-19 6 views
21

J'ai un champ de recherche dans mon application WPF avec un bouton de recherche qui contient une commande de liaison. Cela fonctionne très bien, mais comment puis-je utiliser la même commande de liaison pour le champ de texte en appuyant sur Entrée sur le clavier? Les exemples que j'ai vus utilisent tous le code derrière avec un gestionnaire d'événements KeyDown. Y a-t-il une manière intelligente de faire fonctionner ceci seulement avec xaml et la commande de liaison?WPF: Exécuter une commande de liaison dans un champ de recherche en appuyant sur le bouton Entrée

Répondre

22

Vous pouvez utiliser la propriété IsDefault du bouton:

<Button Command="SearchCommand" IsDefault="{Binding ElementName=SearchTextBox, 
               Path=IsKeyboardFocused}"> 
     Search! 
    </Button> 
+0

Merci, facile et propre. Fonctionne très bien! –

+0

Merci pour ça! – abramlimpin

+0

Que faire si vous n'avez pas de bouton? – ihake

3

L'implémentation de référence Prism contient une implémentation de ce que vous cherchez exactement.

Les bases étapes sont les suivantes:

  • Créer une classe statique EnterKey
  • propriété attachée Registered "Commande" de type ICommand sur EnterKey
  • propriété attachée Registered "EnterKeyCommandBehavior" de type EnterKeyCommandBehavior sur EnterKey
  • Lorsque la valeur de "Command" change, attachez "EnterKeyCommandBehavior" au contrôle en tant que nouvelle instance de EnterKeyCommandBehavior et affectez l'ICommand à la propriété Command du comportement.
    • Si le comportement est déjà fixé, utilisez l'instance existante
  • EnterKeyCommandBehavior accepte un UIElement dans le constructeur et attache à la PreviewKeyDown (ou KeyDown si vous voulez rester compatible Silverlight).
  • Dans le gestionnaire d'événements, si la clé est Entrée, exécutez l'ICommand (si CanExecute a la valeur true).

Cela vous permet d'utiliser le comportement comme ceci:

<TextBox prefix:EnterKey.Command="{Binding Path=SearchCommand}" /> 
23

La réponse acceptée ne fonctionne que si vous avez déjà un bouton lié à la commande.

Pour éviter cette limitation, utilisez TextBox.InputBindings:

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

Merci pour la mise à jour –

+0

Cela a fonctionné pour moi. – Garry

+0

J'ai également dû modifier UpdateSourceTrigger sur ma liaison TextBox.Text pour que cela fonctionne. Pour plus de détails, consultez [Capture de la touche Entrée dans un TextBox] (http://stackoverflow.com/a/5556526/744014). – Scott

0

J'ai essayé la solution TextBox.Inputs de Greg Samson, mais nous avons eu une erreur en disant que je ne pouvais lier à textinputs par une propriété de dépendance . En fin de compte, j'ai trouvé la solution suivante pour cela.

Créer une classe appelée CommandReference qui ressemble à ceci:

public class CommandReference : Freezable, ICommand 
{ 
    public CommandReference() 
    { 
     // 
    } 

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandReference), new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged))); 

    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    #region ICommand Members 

    public bool CanExecute(object parameter) 
    { 
     if (Command != null) 
      return Command.CanExecute(parameter); 
     return false; 
    } 

    public void Execute(object parameter) 
    { 
     Command.Execute(parameter); 
    } 

    public event EventHandler CanExecuteChanged; 

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     CommandReference commandReference = d as CommandReference; 
     ICommand oldCommand = e.OldValue as ICommand; 
     ICommand newCommand = e.NewValue as ICommand; 

     if (oldCommand != null) 
     { 
      oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged; 
     } 
     if (newCommand != null) 
     { 
      newCommand.CanExecuteChanged += commandReference.CanExecuteChanged; 
     } 
    } 

    #endregion 

    #region Freezable 

    protected override Freezable CreateInstanceCore() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

En XAML ajouter ceci aux ressources UserControl:

<UserControl.Resources> 
    <Base:CommandReference x:Key="SearchCommandRef" Command="{Binding Path = SomeCommand}"/> 

La TextBox réelle ressemble à ceci:

<TextBox Text="{Binding Path=SomeText}"> 
        <TextBox.InputBindings> 
         <KeyBinding Command="{StaticResource SearchCommandRef}" Key="Enter"/> 
        </TextBox.InputBindings> 
       </TextBox> 

Je ne me souviens pas d'où j'ai eu ce code, mais ce site l'explique aussi;

http://www.netframeworkdev.com/windows-presentation-foundation-wpf/invoke-a-command-with-enter-key-after-typing-in-a-textbox-21909.shtml

Questions connexes