2
votes

Suppose I have usercontrol with textbox, combobox, button,... inside this control.

Button1 is bound to a ICommand in view model.

My request is: when user hit Enter key in any field, like any textbox, combobox, it will fire Button1 Click event, so that ICommand will be called.

How to implement this?

2

2 Answers

3
votes

I created simple behaviour for this kind of situation

<TextBox Grid.Row="2" x:Name="Tags">
    <i:Interaction.Behaviors>
       <this:KeyEnterCommand Command="{Binding AddTagsCommand}" CommandParameter="{Binding ElementName=Tags}" />
    </i:Interaction.Behaviors>
</TextBox>

behaviour code:

public class KeyEnterCommand : Behavior<Control>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.KeyDown += KeyDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.KeyDown -= KeyDown;
    }

    void KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Enter && Command != null)
        {
            Command.Execute(CommandParameter);
        }
    }

    #region Command (DependencyProperty)

    /// <summary>
    /// Command
    /// </summary>
    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(KeyEnterCommand),
            new PropertyMetadata(null));

    #endregion

    #region CommandParameter (DependencyProperty)

    /// <summary>
    /// CommandParameter
    /// </summary>
    public object CommandParameter
    {
        get { return (object)GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(KeyEnterCommand),
            new PropertyMetadata(null));


    #endregion
}
0
votes

Add a dependency property to the UserControl:-

public ICommand EnterKeyCommand
{
    get { return GetValue(EnterKeyCommandProperty) as ICommand; }
    set { SetValue(EnterKeyCommandProperty, value); }
}

public static readonly DependencyProperty EnterKeyCommandProperty =
        DependencyProperty.Register(
                "EnterKeyCommand",
                typeof(ICommand),
                typeof(MyControl),
                null);

Attach a handler for the Keyup event on the UserControl using the AddHandler method:-

void MyControl()
{

    InitializeComponent();
    this.AddHandler(UIElement.KeyUpEvent, new KeyEventHandler(UserControl_KeyUp), true);  //Note that last parameter important
}

void UserControl_KeyUp(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Enter && EnterKeyCommand != null && EnterKeyCommand.CanExecute(null))
   {
       EnterKeyCommand.Execute(null);
   }

}

Note the point here is that the use of AddHandler allows you to intercept an event that has already been handled.

Also note that this is simplified for clarity. In reality you would also want to implement another dependency property for the Command parameter and pass that to CanExecute and Execute instead of null. You would also need to detect whether the OriginalSource is a TextBox that has AcceptsReturn set to true.