7

I've a Text box KeyUp Event Trigger Wired up to a command in WPF. I need to pass the actual key that was pressed as a command parameter.

The command executes fine, but the code that handles it needs to know the actual key that was pressed (remember this could be an enter key or anything not just a letter, so I can't get it from the TextBox.text).

Can't figure out how to do this. XAML:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

XAML:

<TextBox Height="23" Name="TextBoxSelectionSearch" Width="148" Tag="Enter Selection Name" Text="{Binding Path=SelectionEditorFilter.SelectionNameFilter,UpdateSourceTrigger=PropertyChanged}" >
       <i:Interaction.Triggers>
          <i:EventTrigger EventName="KeyUp">
             <i:InvokeCommandAction Command="{Binding SelectionEditorSelectionNameFilterKeyUpCommand}" />
          </i:EventTrigger>
       </i:Interaction.Triggers>
</TextBox>
DermFrench
  • 3,968
  • 13
  • 43
  • 70
  • I used MVVMLight, and can pass `EventArgs` like: http://stackoverflow.com/a/6205643/352101 – Bolu Sep 25 '13 at 15:05

1 Answers1

10

I don't think that's possible with InvokeCommandAction but you can quickly create your own Behavior which could roughly look like this one:

public class KeyUpWithArgsBehavior : Behavior<UIElement>
{
    public ICommand KeyUpCommand
    {
        get { return (ICommand)GetValue(KeyUpCommandProperty); }
        set { SetValue(KeyUpCommandProperty, value); }
    }

    public static readonly DependencyProperty KeyUpCommandProperty =
        DependencyProperty.Register("KeyUpCommand", typeof(ICommand), typeof(KeyUpWithArgsBehavior), new UIPropertyMetadata(null));


    protected override void OnAttached()
    {
        AssociatedObject.KeyUp += new KeyEventHandler(AssociatedObjectKeyUp);
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.KeyUp -= new KeyEventHandler(AssociatedObjectKeyUp);
        base.OnDetaching();
    }

    private void AssociatedObjectKeyUp(object sender, KeyEventArgs e)
    {
        if (KeyUpCommand != null)
        {
            KeyUpCommand.Execute(e.Key);
        }
    }
}

and then just attach it to the TextBox:

<TextBox Height="23" Name="TextBoxSelectionSearch" Width="148" Tag="Enter Selection Name" Text="{Binding Path=SelectionEditorFilter.SelectionNameFilter,UpdateSourceTrigger=PropertyChanged}" >
   <i:Interaction.Behaviors>
          <someNamespace:KeyUpWithArgsBehavior
                 KeyUpCommand="{Binding SelectionEditorSelectionNameFilterKeyUpCommand}" />
   </i:Interaction.Behaviors>
</TextBox>

With just that you should receive the Key as a parameter to the command.

dmusial
  • 1,504
  • 15
  • 14
  • Hey sorry I've now realized I want the full event args (not just the key pressed) but your answer works for key press, any tips on how to get full event args? – DermFrench Sep 25 '13 at 22:44
  • Yeah that worked for me - many thanks (just doing .Execute(e) instead of .Execute(e.key) gives full event args. Superb! – DermFrench Sep 25 '13 at 22:51
  • The events aren't being passed for special key like enter, tab, up, down etc. How can I get KeyEvent for them too ? FYI, I am using KeyDown instead of KeyUp and using aa custom text box. It works fine for other buttons like alphabets and numbers. – lukai Oct 18 '16 at 07:32