0

I need to design a control that will capture the key stroke a user has pressed and treat that as the input.

I then need to display it to the user so they know which one they pressed.

I've tried using a textbox, and wiring up to the ValueChanged event, but it shows the key twice for some reason.

Does anyone know of a control that is already built that might handle this functionality?

Sidenote: I don't need an implementation with modifier keys or anything like that, I'm just trying to track a single key stroke for the time being.

Another way of looking at it is: In pretty much every PC video game, you can change the key bindings in the settings of the game. You go to the settings, find the key binding you're looking for, select it, and then hit a keystroke, then it captures that keystroke and changes the key binding to the keystroke the user entered.

That is exactly the functionality I'm looking for.

Joseph
  • 25,330
  • 8
  • 76
  • 125

3 Answers3

2

The simple way to do this would be data binding. In WPF this is quite easy. You can bind the data from one control to another. Below I have bound a TextBox, which has taken the user input, to a Label which displays it.

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox Height="23" HorizontalAlignment="Left" Margin="45,55,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    <Label Content="{Binding ElementName=textBox1, Path=Text}" Height="28" HorizontalAlignment="Left" Margin="45,135,0,0" Name="label1" VerticalAlignment="Top" Width="142" />
</Grid>

The more complex answer would be to do Command binding. What this does is catches specific key bindings on a UserControl or Window and executes a given command. This is a little more complex because it requires you to create a class that implements ICommand.

More info here: http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx

I personally am a big fan of the RelayCommand implementation by Josh Smith. There is a great article here.

In short though you can do this.

XAML:

<Window.InputBindings>
        <KeyBinding Key="Escape" Command="{Binding KeyPressCommand}"/>
</Window.InputBindings>

CODE: You will need to create a RelayCommand Class.

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }

And then to implement this in your main window you will need to do this.

 private RelayCommand _keyPressCommand;

    public RelayCommand KeyPressCommand
    {
        get
        {
            if (_keyPressCommand== null)
            {
                _keyPressCommand = new RelayCommand(
                 KeyPressExecute,
                 CanKeyPress);
            }
            return _keyPressCommand;
        }
    }

private void KeyPressExecute(object p)
{
    // HANDLE YOUR KEYPRESS HERE
}

private bool CanSaveZone(object parameter)
{
   return true;
}

If you go with the second option I really suggest you take a look at the MSDN article by Josh Smith.

nickm
  • 1,775
  • 1
  • 12
  • 14
0

You have to catch the form event for this case, Refer this Stack Overflow repeated question, it will provide you the answer

Fire Form KeyPress event

Community
  • 1
  • 1
las
  • 196
  • 8
  • I know how to capture the key event, that's not my problem. My issue is making a control work where it will only respond to a single key event (not multiple) and display what that key event was. – Joseph Apr 17 '12 at 02:31
  • What is the control you want to work and what is the event you want to track ? – las Apr 17 '12 at 06:21
  • I think KeyDown is the best way to your problem,Refer this MSDN link http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown.aspx – las Apr 17 '12 at 06:43
  • What I'm asking for is what kind of control to use for this sort of functionality. My first take on this was to use a textinput and override the KeyDown event, but it's not working the way I need it to. I need a control that can capture a SINGLE key event and show what the user pressed. – Joseph Apr 17 '12 at 12:53
  • why don't you use form control ?Form events are the events trigger first than other controls in the form, so its good to use form control and its events – las Apr 18 '12 at 03:19
  • and also check this http://www.codeproject.com/Articles/20550/C-Event-Implementation-Fundamentals-Best-Practices – las Apr 18 '12 at 03:27
0

What I ended up having to do was this:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox Name="textBox1" PreviewKeyDown="previewKeyDown" />
</Grid>

and then in my even handler do this:

private void previewKeyDown(object sender, KeyEventArgs e)
{
    e.Handled = true;
    textBox1.Text = e.Key.ToString();
}

This basically disabled the default key functionality of the text box by setting

e.Handled =  true

and then I changed the text of the textbox to be what I needed, which was the key that was pressed.

Joseph
  • 25,330
  • 8
  • 76
  • 125