如何使用keybord焦点创建非活动下拉列表 [英] How to create a non active dropdown with keybord focus
本文介绍了如何使用keybord焦点创建非活动下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想创建一个下拉控件,该控件应该处于非活动状态并具有键盘输入焦点。所以我创建了一个控件如下。
I want to create a dropdown control which should be inactive and have keyboard input focus. So I created a control as below.
public class DropDownEdit : UserControl
{
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private const int WS_EX_TOOLWINDOW = 0x00000080;
private const int WS_EX_TOPMOST = 0x00000008;
private const int WS_EX_NOACTIVATE = 0x08000000;
private const int WS_CHILD = 0x40000000;
private const int WS_POPUP = unchecked((int)0x80000000);
private TextBox text = new TextBox();
public DropDownEdit()
{
this.BackColor = Color.FromArgb(44, 68, 107);
this.Controls.Add(text);
this.Margin = Padding.Empty;
this.Padding = new Padding(0);
text.Multiline = true;
text.ScrollBars = ScrollBars.Both;
text.Size = new Size(this.Width, this.Height);
}
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.Style &= ~WS_CHILD;
createParams.Style |= WS_POPUP;
createParams.ExStyle |= WS_EX_TOOLWINDOW;
createParams.ExStyle |= WS_EX_TOPMOST;
createParams.ExStyle |= WS_EX_NOACTIVATE;
return createParams;
}
}
public void ShowWindow(Point point)
{
text.Focus();
this.Capture = true;
SetParent(this.Handle, IntPtr.Zero);
this.Location = point;
Show();
}
protected override void OnMouseCaptureChanged(EventArgs e)
{
base.OnMouseCaptureChanged(e);
this.Hide();
}
}
当我显示上面的下拉窗口时,
And when I am displaying the above dropdown window as below,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Point point = this.PointToScreen(button1.Location);
DropDownEdit window = new DropDownEdit();
window.ShowWindow(new Point(point.X, point.Y + 20));
}
}
Form1
有一个显示 DropDownEdit
时闪烁。我认为 DropDownEdit
被激活, Form1
失去激活。如何在 Form1
中避免这种闪烁?
注意: - 我需要输入焦点 TextBox
在下拉控件中。
The Form1
has a flickering while displaying DropDownEdit
. I think DropDownEdit
get activated and Form1
loses its activation. How can I avoid this flickering in Form1
?
NB:- I need input focus on TextBox
in the dropdown control.
推荐答案
听听它的声音是非主动下拉键盘焦点。什么不活动可以有键盘焦点?为什么?它可能做什么?它似乎没有任何意义。
你遇到的另一个问题是使用P / Invoke。您不需要P / Invoke来设置父级。父母是通过作业设定的
Just listen how it sounds "non-active drop down with keyboard focus". How anything inactive could have keyboard focus? Why? what it could possibly do? It does not seem to make any sense.
Another problem you have is using P/Invoke. You don't need P/Invoke to set a parent. A parent is set by assignment
myControl.Parent = someOtherControl;
或使用
or using
someOtherControl.Controls.Add(myControl);
P / Invoke不是绝对必需的,它使用起来很糟糕;它会破坏你代码的平台兼容性。
我找到了解决方案。
显示我的下拉窗口时,它将收到激活,Windows将停用主窗口。解决此问题的方法是向父级发送WM_NCACTIVATE
消息,以更新其可视外观而不更改其激活状态。以下代码在DropDownEdit
类中更新以解决我的问题。
I found a solution.
While displaying my dropdown window it will receive activation and Windows will deactivate the main window. The fix for this is to send aWM_NCACTIVATE
message to the parent to update its visual appearance without changing its activation status. The below code is updated inDropDownEdit
class to solve my issue.
private const int WM_NCACTIVATE = 0x86;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
protected override void WndProc(ref Message m)
{
// The popup needs to be activated for the user to interact with it,
// but we want to keep the owner window's appearance the same.
if ((m.Msg == WM_NCACTIVATE) && !_activating && (m.WParam != IntPtr.Zero))
{
// The popup is being activated, ensure parent keeps activated appearance
_activating = true;
SendMessage(this.Owner.Handle, WM_NCACTIVATE, (IntPtr) 1, IntPtr.Zero);
_activating = false;
// Call base.WndProc here if you want the appearance of the popup to change
}
else
{
base.WndProc(ref m);
}
}
这篇关于如何使用keybord焦点创建非活动下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文