3

我知道 Windows 窗体的 KeyPreview 属性,这允许窗体在传递给焦点控件之前接收键事件。

但是,我希望表单在到达焦点控件后接收事件。

作为测试,我在表单上放置了一个文本框。在 TextBox 中键入后,它应该在按下某些键命令时执行它的默认行为。Ctrl-S、F1 等,我希望那些通过 TextBox 冒泡到要在更高级别处理的表单。这些命令是 TextBox 默认不执行的命令。

我确实需要事件首先通过 TextBox。需要此功能的应用程序比这个简单的示例更复杂。例如,当 TextBox 是焦点控件时,它应该使用 Ctrl-C 和 Ctrl-V 执行默认的复制和粘贴。但是,当关注各种其他控件时,这些命令需要最终在最顶层的表单级别进行处理。

编辑: 似乎输入事件从表单转到焦点控制,而不是像我期望的那样相反。如果它从焦点转到表单,我可能不会遇到我遇到的问题。

Edit2: 通过这篇文章(简要地)阅读:http: //www.codeproject.com/KB/WPF/BeginWPF3.aspx我现在假设我期待的那种“冒泡”只是“在那里”是仅在 WPF 中可用,而不是标准 C#。我认为我将不得不重新考虑用户与我的应用程序交互的方式,而不是编写大量丑陋的代码。

任何人都可以在没有丑陋代码的情况下回复在 C# 中进行 WPF 样式冒泡的人。

4

4 回答 4

2

您仍然可以使用 KeyPreview 属性,但检查哪个控件被聚焦,如果它是一个文本框则什么也不做,否则如果它是另一个控件 - 比如 RichTextBox - 然后处理按下的键。要获得当前集中的控制,您可能需要访问 Win32 API。示例:新建一个 Windows 窗体应用程序,在窗体中添加一个文本框和一个富文本框,将窗体的 KeyPreview 属性设置为 true,为窗体、文本框和富文本框的 KeyDown 事件添加事件处理程序。还有以下 using 语句:

using System.Runtime.InteropServices;//for DllImport

然后将表单的代码替换为以下代码:

public partial class Form1 : Form
{
    // Import GetFocus() from user32.dll
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr GetFocus();

    protected Control GetFocusControl()
    {
        Control focusControl = null;
        IntPtr focusHandle = GetFocus();
        if (focusHandle != IntPtr.Zero)
            // returns null if handle is not to a .NET control
            focusControl = Control.FromHandle(focusHandle);
        return focusControl;
    } 

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        Control focusedControl = GetFocusControl();
        if (focusedControl != null && !(focusedControl is TextBox) && e.Control && e.KeyCode == Keys.C)//not a textbox and Copy
        {
            MessageBox.Show("@Form");
            e.Handled = true;
        }
    }

    private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if(e.Control && e.KeyCode == Keys.C)
            MessageBox.Show("@Control");
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.C)
            MessageBox.Show("@Control");
    }
}
于 2010-02-18T01:45:28.433 回答
0

查看下面给出的链接。

http://www.vbdotnetforums.com/windows-forms/30257-solved-ctrl-s-combobox.html

希望这可以帮助。

问候, 拉贾

于 2010-02-17T15:24:20.043 回答
0

不幸的是,您必须手动实现它 - 在您的表单中实现 KeyDown 事件处理程序,检查全局组合键并为它们设置 KeyPressEventArgs.Handled = true。

供参考:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown.aspx

于 2010-02-17T15:26:30.197 回答
-1

您可以为文本框的 KeyPress 和/或 KeyUp/KeyDown 事件实现事件处理程序。

在 KeyPress 事件的事件处理程序中,如果Handled将事件 args 上的属性设置为true,则不会将事件传递到文本框。如果您不将其设置为true,它将是。

(编辑以澄清第二段)。

于 2010-02-17T15:27:58.587 回答