'Focus a child Control of a User Control when a combination of keys is pressed
I have a Form that contains a Panel where I placed a UserControl.
I want that when the Ctrl+F Keys combination is pressed, a TextBox Control, child of my UserControl, gets the Focus.
The structure is like this:
So far, I've tried to handle the KeyPreview
and KeyDown
events. I can show a MessegeBox:
but I cannot focus the TextBox inside my UserControl.
How can I solve this problem?
Solution 1:[1]
You can probably implement IMessageFilter and handle the Keys combinations you want.
You then have to use Application.AddMessageFilter() to add the message filter and Application.RemoveMessageFilter() to remove it when not needed anymore.
Here, the UserControl's DesignMode property is checked, so the filter is added at run.time only.
Possibly, add a public Property that can add / remove / change combinations of Keys, in case there's a conflict with other controls.
The GetAncestor() function is used to determine whether the Form where the Keys combination is triggered is the Parent Form of this instance of the UserControl.
PreFilterMessage() is called when messages are generated in any Form of the application.
If you instead want to perform an action in any case, even when the combination is generated in another open Form (and, maybe, pop the Parent Form in front), just remove that check.
Filter Control + F.
If you need more filters, as mentioned, use a collection to handle these combinations.
When WM_KEYDOWN is received, WParam
contains the virtual Key Code. The Virtual Key value is equivalent to the Keys enumerator.
THe ModifierKeys property contains the Key Modifiers currently active (the Control key alone is tested here, of course you can add other shortcuts that use, e.g. 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, GA_PARENT).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;
private const int GA_PARENT = 0x0002;
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetAncestor(IntPtr hWnd, uint flags);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |