按下组合键时聚焦用户控件的子控件
Posted
技术标签:
【中文标题】按下组合键时聚焦用户控件的子控件【英文标题】:Focus a child Control of a User Control when a combination of keys is pressed 【发布时间】:2021-10-24 18:13:47 【问题描述】:我有一个表单,其中包含一个面板,我在其中放置了一个用户控件。 我希望当按下 Ctrl+F 组合键时,我的 UserControl 的子 TextBox 控件获得焦点。
结构是这样的:
到目前为止,我已经尝试处理 KeyPreview
和 KeyDown
事件。我可以显示一个 MessegeBox:
但我无法将文本框集中在我的 UserControl 中。 我该如何解决这个问题?
【问题讨论】:
【参考方案1】:您可能可以实现IMessageFilter 并处理您想要的组合键。 然后,您必须使用 Application.AddMessageFilter() 添加消息过滤器,并在不再需要时使用 Application.RemoveMessageFilter() 将其删除。
这里,UserControl 的DesignMode 属性被选中,所以过滤器只在run.time 添加。
可能,添加一个可以添加/删除/更改键组合的公共属性,以防与其他控件发生冲突。
GetAncestor()函数用于判断触发Keys组合的Form是否是UserControl这个实例的Parent Form。PreFilterMessage()在应用的任意Form生成消息时调用. 如果您想在任何情况下执行某个操作,即使组合是在另一个打开的表单中生成的(并且可能会弹出前面的父表单),只需删除该检查即可。
过滤 Control + F。 如前所述,如果您需要更多过滤器,请使用集合来处理这些组合。
当收到WM_KEYDOWN 时,WParam
包含虚拟密钥代码。虚拟键值相当于Keys 枚举器。ModifierKeys 属性包含当前活动的键修饰符(此处仅测试 Control 键,当然您可以添加其他使用的快捷键,例如 CTRL+SHIFT)。
using System.ComponentModel;
using System.Runtime.InteropServices;
public partial class SomeUserControl : UserControl, IMessageFilter
public SomeUserControl() => InitializeComponent();
public bool PreFilterMessage(ref Message m)
if (m.Msg == WM_KEYDOWN)
if (GetAncestor(m.HWnd, 2).Equals(ParentForm.Handle))
if (m.WParam.ToInt32() == (int)Keys.F && ModifierKeys == Keys.Control)
someChildTextBox.Focus();
return false;
protected override void OnHandleCreated(EventArgs e)
base.OnHandleCreated(e);
if (!DesignMode) Application.AddMessageFilter(this);
protected override void OnHandleDestroyed(EventArgs e)
if (!DesignMode) Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
private const int WM_KEYDOWN = 0x0100;
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetAncestor(IntPtr hWnd, uint flags);
【讨论】:
感谢您的回答,我试过了,它解决了我的问题。 (实际上,我从您的第一条评论中看不懂(因为我是 C# 新手)并且不知道如何使用)。无论如何,再次感谢。以上是关于按下组合键时聚焦用户控件的子控件的主要内容,如果未能解决你的问题,请参考以下文章
按下返回键时如何在下一个 UITextField 上移动控件
emWin 2天速成实例教程005_控件聚焦和用户消息的使用方法