2009-10-19 28 views
21

Tengo un campo de búsqueda en mi aplicación WPF con un botón de búsqueda que contiene un enlace de comando. Esto funciona muy bien, pero ¿cómo puedo usar el mismo enlace de comando para el campo de texto al presionar Enter en el teclado? Los ejemplos que he visto están usando el código detrás con un manejador de eventos KeyDown. ¿Hay alguna manera inteligente de hacer que esto funcione solo con xaml y el enlace del comando?WPF: Ejecutar un Enlace de comando en un campo de búsqueda al presionar el botón Entrar

Respuesta

22

Usted puede utilizar la propiedad IsDefault del botón:

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

Gracias, fácil y limpio. ¡Funciona genial! –

+0

¡Gracias por esto! – abramlimpin

+0

¿Qué sucede si no tiene un botón? – ihake

3

La implementación de referencia Prism contiene una implementación de lo que está buscando exactamente.

Los pasos básicos son:

  • crear una clase estática enterkey
  • registrada propiedad adjunta "Comando" del tipo ICommand en enterkey
  • registrada propiedad adjunta "EnterKeyCommandBehavior" del tipo EnterKeyCommandBehavior en enterkey
  • Cuando el valor de "Comando" cambia, adjunte "EnterKeyCommandBehavior" al control como una nueva instancia de EnterKeyCommandBehavior, y asigne ICommand a la propiedad Comando del comportamiento.
    • Si el comportamiento ya ha sido fijada, utilice la instancia existente
  • EnterKeyCommandBehavior acepta UIElement en el constructor y se une a la PreviewKeyDown (o KeyDown si desea permanecer Silverlight compatibles).
  • En el controlador de eventos, si la clave es Enter, ejecute el ICommand (si CanExecute es verdadero).

Esto le permite utilizar el comportamiento de este modo:

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

La respuesta aceptada sólo funciona si ya tiene una botón vinculado al comando.

Para evitar esta limitación, utilice TextBox.InputBindings:

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

Gracias por la actualización –

+0

Esto funcionó para mí. – Garry

+0

Además tuve que cambiar UpdateSourceTrigger en mi enlace TextBox.Text para que esto funcione. Para obtener más detalles, consulte [Capturar la tecla Intro en un cuadro de texto] (http://stackoverflow.com/a/5556526/744014). – Scott

0

que he probado la solución TextBox.Inputs de Greg Samson, pero tiene un error que indica que sólo podía unirse a textinputs a través de una propiedad de dependencia . Al final he encontrado la siguiente solución para esto.

Crear una clase llamada CommandReference que se parece a esto:

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 añadir esto a los Recursos UserControl:

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

El cuadro de texto actual se parece a esto:

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

No recuerdo de dónde obtuve este código, pero este sitio lo explica también;

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

Cuestiones relacionadas