简体   繁体   English

设计按键控制的最佳方法是什么?

[英]What is the best way to design a Key Pressed Control?

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. 我已经尝试使用文本框,并连接到ValueChanged事件,但由于某种原因它显示了两次键。

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. 另一种看待它的方式是:在几乎所有PC视频游戏中,您都可以在游戏设置中更改键绑定。 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. 正是我正在寻找的功能。

The simple way to do this would be data binding. 执行此操作的简单方法是数据绑定。 In WPF this is quite easy. 在WPF中,这很容易。 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. 下面我将一个带有用户输入的TextBox绑定到显示它的Label上。

<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. 更复杂的答案是进行Command绑定。 What this does is catches specific key bindings on a UserControl or Window and executes a given command. 这样做是捕获UserControl或Window上的特定键绑定并执行给定的命令。 This is a little more complex because it requires you to create a class that implements ICommand. 这有点复杂,因为它要求您创建一个实现ICommand的类。

More info here: http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx 更多信息: 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. 我个人是Josh Smith执行RelayCommand的忠实粉丝。 There is a great article here . 有一个伟大的文章在这里

In short though you can do this. 简而言之,你可以做到这一点。

XAML: XAML:

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

CODE: You will need to create a RelayCommand Class. 代码:您需要创建一个RelayCommand类。

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. 如果你选择第二个选项我真的建议你看一下Josh Smith的MSDN文章。

You have to catch the form event for this case, Refer this Stack Overflow repeated question, it will provide you the answer 您必须捕获此案例的表单事件,请参阅此Stack Overflow重复的问题,它将为您提供答案

Fire Form KeyPress event Fire Form KeyPress事件

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. 然后我将文本框的文本更改为我需要的内容,这是按下的键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM