如何将关键事件从控件冒泡到窗体?

发布于 2024-08-22 02:22:34 字数 784 浏览 10 评论 0原文

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

但是,我希望窗体在事件到达焦点控件后接收该事件。

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

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

编辑: 看来输入事件是从表单到焦点控制,而不是像我预期的那样相反。如果它从焦点转向形式,我可能不会遇到我所遇到的问题。

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

对于任何能够在 C# 中实现 WPF 风格的冒泡而无需丑陋代码的人来说,这都是很重要的。

I am aware of the KeyPreview property of a Windows Form, and this allows the Form to receive the key events before they get passed to the focused control.

However, I want the Form to receive the event after it has been to the focused control.

As a test I have placed a TextBox on a Form. Upon typing in the TextBox it should perform it's default behavior, upon pressing certain key commands. Ctrl-S, F1, etc, I want those to bubble through the TextBox up to the Form to be handled at a higher level. These commands are those that the TextBox doesn't do by default.

I do need the events to go through the TextBox first though. The application this functionality is needed in is more complex than this simple example. For example, when the TextBox is the focused control it should perform the default Copy & Paste using Ctrl-C and Ctrl-V. However, when various other controls are focused these commands need to end up at the top-most Form-level to be processed there.

Edit:
It seems that input events go from Form to Focused Control and not the other way around like I was expecting. If it went from Focus to Form I probably wouldn't be having the problem I have.

Edit2:
Having read (briefly) though this article: http://www.codeproject.com/KB/WPF/BeginWPF3.aspx I am now assuming that the sort of 'bubbling' that I was expecting to just 'be there' is only available in WPF, and not standard C#. I think I'm going to have to re-think the way in which the users interact with my app as opposed to writing swathes of ugly code.

Big points to anyone who can reply on doing WPF-style bubbling in C# without ugly code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼角的笑意。 2024-08-29 02:22:35

查看下面给出的链接。

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

希望这有帮助。

问候,
拉惹

Check out the link given below.

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

Hope this helps.

Regards,
Raja

月下凄凉 2024-08-29 02:22:35

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

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

You have to implement it manually unfortunately - implement the KeyDown event handler in your form, check for the global key combinations and set KeyPressEventArgs.Handled = true for them.

For reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown.aspx

夏夜暖风 2024-08-29 02:22:35

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

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

(编辑以澄清第二段)。

You can implement an event handler for the textbox's KeyPress and/or KeyUp/KeyDown events.

In your event handler of the KeyPress event, if you set the Handled property on the event args to true, then the event will not be passed on to the textbox. If you don't set it to true, it will be.

(Edited to clarify the second paragraph).

公布 2024-08-29 02:22:34

您仍然可以使用 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");
    }
}

You may still use KeyPreview property but check which control is focused, if it is a textbox then do nothing, else if it is another control - say RichTextBox - then handle the pressed keys.
To get the currently focused control, you may need to access Win32 API.
Example: Created a new Windows forms application, add a text box and a richtext box in the form, set the KeyPreview property of the form to true, add an event handler for the KeyDown event of the form, the textbox, and the richtextbox. Also the following using statement:

using System.Runtime.InteropServices;//for DllImport

then replace the code of the form by the following code:

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");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文