WPF:一个具有在按下回车键时触发事件的文本框

29

我在我的应用程序中不想为每个TextBox附加PreviewKeyUp事件并检查按下的键是否为Enter键,然后执行操作。相反,我决定实现一个扩展版本的TextBox,其中包括在TextBox中按下Enter键时触发DefaultAction事件。

我所做的基本上是创建一个从TextBox继承的新类,具有公共事件DefaultAction,如下所示:

public class DefaultTextBoxControl:TextBox
{
    public event EventHandler<EventArgs> DefaultAction = delegate { };

    public DefaultTextBoxControl()
    {
        PreviewKeyUp += DefaultTextBoxControl_PreviewKeyUp;
    }

    void DefaultTextBoxControl_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key != Key.Enter)
        {
            return;
        }
        DefaultAction(this, EventArgs.Empty);
    }
}

接下来我会像这样在我的应用程序中使用自定义文本框(XAML):

<Controls:DefaultTextBoxControl  DefaultAction="DefaultTextBoxControl_DefaultAction">
</Controls:DefaultTextBoxControl>

根据我的一些经验,在学习WPF时,我意识到几乎大部分时间都有一种“更酷”(而且希望更容易)的实现方式。

...所以我的问题是,如何改进上述控件? 或者也许有另一种方法可以完成上述控件? ...也许只使用声明性代码而不是同时使用声明性(XAML)和过程性(C#)的代码?

6个回答

45

请看几个月前的博客文章,我在其中附加了一个“全局”事件处理程序到TextBox.GotFocus 以选择文本。

本质上,您可以在您的App类中处理KeyUp事件,就像这样:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.KeyUpEvent,
        new System.Windows.Input.KeyEventHandler(TextBox_KeyUp));

    base.OnStartup(e);
}

private void TextBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key != System.Windows.Input.Key.Enter) return;

    // your event handler here
    e.Handled = true;
    MessageBox.Show("Enter pressed");
}

...现在你的应用程序中的每个TextBox在用户输入时都会调用TextBox_KeyUp方法。

更新

正如您在评论中指出的那样,只有在每个TextBox需要执行相同的代码时才有用。

要添加任意事件,例如按Enter键,您最好查看附加事件。我相信这可以帮助您获得所需的内容。


但是,如何分配按下回车键时发生的事件呢?因为每个文本框都有不同的功能。 - Andreas Grech

36

自从提出这个问题以来,现在在文本框和其他控件上有一个名为InputBindings的属性。通过使用它,可以使用纯XAML解决方案,而无需使用自定义控件。将 KeyBinding 分配给指向命令的ReturnEnter 可以实现此目的。

例如:

<TextBox Text="Test">
    <TextBox.InputBindings>
        <KeyBinding Command="{Binding SomeCommand}" Key="Return" />
        <KeyBinding Command="{Binding SomeCommand}" Key="Enter" />
    </TextBox.InputBindings>
</TextBox>

有些人提到Enter不总是有效,某些系统上可以使用Return


看起来不错,所以我尝试了一下,但是它不起作用。使用按钮时,我的命令会被触发,但使用文本框时却不行。我甚至添加了 Source={StaticResource viewModel},但仍然没有效果。 - Matthis Kohli
1
在阅读这个答案时,我成功地跳过了Matthis Kohli的评论,并将其应用到我的情况中,幸运的是它确实触发了相关的方法。 - Peter Nimmo
似乎需要使用UpdateSourceTrigger=PropertyChanged - undefined

10
当用户在文本框中按下回车键时,文本框中的输入将出现在用户界面(UI)的另一个区域。
以下XAML创建了用户界面,包括StackPanel、TextBlock和TextBox。
<StackPanel>
  <TextBlock Width="300" Height="20">
    Type some text into the TextBox and press the Enter key.
  </TextBlock>
  <TextBox Width="300" Height="30" Name="textBox1"
           KeyDown="OnKeyDownHandler"/>
  <TextBlock Width="300" Height="100" Name="textBlock1"/>
</StackPanel>

以下是代码后台创建的KeyDown事件处理程序。如果按下的键是Enter键,则在TextBlock中显示一条消息。
private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        textBlock1.Text = "You Entered: " + textBox1.Text;
    }
}

更多信息请阅读 MSDN 文档。


谢谢您包含了C#方面的内容。其他答案都让我得到了一个不完整的程序。 - Alan Baljeu

0

否则你可以用C#做任何事情,比如:

//at the constructor, subscribe your textbox to the KeyUp event
YOUR_TEXTBOX.KeyUp += OnKeyUp;

//listen to the event
private void OnKeyUp(object sender, KeyEventArgs e)
{
   //when typing, listen to the "Enter" key
   if (e.Key == Key.Enter)
        Search(); //do something
}

-1
    private void txtBarcode_KeyDown(object sender, KeyEventArgs e)
    {
        string etr = e.Key.ToString();

        if (etr == "Return")
        {
            MessageBox.Show("You Press Enter");
        }
    }

-2

XAML 中为特定的文本框或对象添加事件:

KeyDown="txtBarcode_KeyDown"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接