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

时间:2012-04-17 01:52:53

标签: c# wpf

我需要设计一个控件来捕捉用户按下的按键,并将其视为输入。

然后我需要将它显示给用户,以便他们知道他们按下了哪一个。

我尝试过使用文本框,并连接到ValueChanged事件,但由于某种原因它会显示两次密钥。

有没有人知道已经构建的控件可能会处理此功能?

旁注:我不需要使用修饰键或类似的实现,我只是想暂时跟踪一个键击。

另一种看待它的方式是:在几乎所有PC视频游戏中,您都可以在游戏设置中更改键绑定。您转到设置,找到您正在寻找的键绑定,选择它,然后点击击键,然后它捕获该击键并将键绑定更改为用户输入的击键。

正是我正在寻找的功能。

3 个答案:

答案 0 :(得分:2)

执行此操作的简单方法是数据绑定。在WPF中,这很容易。您可以将数据从一个控件绑定到另一个控件。下面我将一个带有用户输入的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>

更复杂的答案是进行Command绑定。这样做是捕获UserControl或Window上的特定键绑定并执行给定的命令。这有点复杂,因为它要求您创建一个实现ICommand的类。

更多信息: http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx

我个人非常喜欢Josh Smith的RelayCommand实施。有一篇很棒的文章here

简而言之,你可以这样做。

<强> XAML:

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

<强> CODE: 您需要创建一个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);
    }

然后要在主窗口中实现此功能,您需要执行此操作。

 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;
}

如果您使用第二个选项,我建议您查看Josh Smith撰写的MSDN文章。

答案 1 :(得分:0)

您必须抓住此案例的表单事件, 请参阅Stack Overflow重复问题,它将为您提供答案

Fire Form KeyPress event

答案 2 :(得分:0)

我最终要做的是:

<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>

然后在我的偶数处理程序中执行此操作:

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

这基本上通过设置

禁用了文本框的默认键功能
e.Handled =  true

然后我将文本框的文本更改为我需要的内容,这是按下的键。