ale*_*aro 5 .net c# combobox winforms dropdown
我有一个包含几个组合框的表单。
我希望其中一个 ComboBox 在从键盘和鼠标获得焦点时打开元素列表。
DroppedDownComboBox 类的属性管理元素列表的可见性。
最符合我需求的事件是Enter,所以我写的代码是:
private void comboBox1_Enter(object sender, EventArgs e)
{
this.comboBox1.DroppedDown = true;
}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但是当直接单击位于组合框右侧没有焦点的图标时,元素列表会打开,并且在打开后突然消失。
我尝试了很多方法来修复这种奇怪的行为,检查Focused属性或使用其他事件,如DropDown或MouseClick,但没有得到任何可接受的结果。
一种简单的方法(不会强制您覆盖ComboBox派生的 Control WndProc)是模拟HitTest,测试MouseDown是否发生在ComboBox按钮区域;然后,DroppedDown = true;仅在没有的情况下进行设置。
因此,当鼠标单击按钮时,不会产生双重效果,以意外的方式移动焦点(对于控件)。
GetComboBoxInfo()用于检索 ComboBox 按钮的正确边界,无论当前布局是(LTR 还是 RTL)。
private void comboBox1_Enter(object sender, EventArgs e)
{
var combo = sender as ComboBox;
if (!combo.DroppedDown) {
var buttonRect = GetComboBoxButtonInternal(combo.Handle);
if (!buttonRect.Contains(combo.PointToClient(Cursor.Position))) {
combo.DroppedDown = true;
Cursor = Cursors.Default;
}
}
}
Run Code Online (Sandbox Code Playgroud)
函数声明GetComboBoxInfo():
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);
[StructLayout(LayoutKind.Sequential)]
internal struct COMBOBOXINFO {
public int cbSize;
public Rectangle rcItem;
public Rectangle rcButton;
public int buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
}
internal static Rectangle GetComboBoxButtonInternal(IntPtr cboHandle) {
var cbInfo = new COMBOBOXINFO();
cbInfo.cbSize = Marshal.SizeOf<COMBOBOXINFO>();
GetComboBoxInfo(cboHandle, ref cbInfo);
return cbInfo.rcButton;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2816 次 |
| 最近记录: |