我有一个 Windows 窗体自定义组合框,我在 dataGridView 中托管。我不知道如何在用户选择项目时保持下拉列表打开。没有关闭事件可以挂断。有谁知道这是如何实现的?我会很感激任何建议。
提前致谢,-DA
您可以使用GetComboBoxInfo
获取Handle
并DropDownList
使用 customNativeWindow
挂钩到 的消息循环DropDownList
以捕获一些相关消息并实现您想要的。这是 custom 的完整代码,它具有默认值为ComboBox
的属性,默认情况下它就像标准一样,要使其按您的意愿工作,只需设置:HideDropDownAfterSelect
true
ComboBox
HideDropDownAfterSelect = false
//Must add using System.Runtime.InteropServices;
public static class Win32 {
[DllImport("user32")]
public static extern bool GetComboBoxInfo(IntPtr hwnd,
out Win32.COMBOBOXINFO info);
public struct RECT {
public int left, top, right, bottom;
}
public struct COMBOBOXINFO {
public int size;
public RECT item;
public RECT button;
public int state;
public IntPtr comboHwnd;
public IntPtr itemHwnd;
public IntPtr listHwnd;
}
}
public class CustomComboBox : ComboBox {
NativeDropDownList dropDown = new NativeDropDownList();
IntPtr dropDownHandle;
bool hideDropDownAfterSelect = true;
public CustomComboBox() {
dropDown.ParentControl = this;
HandleCreated += (s, e) => {
Win32.COMBOBOXINFO info = new Win32.COMBOBOXINFO();
info.size = Marshal.SizeOf(info);
Win32.GetComboBoxInfo(Handle, out info);
dropDownHandle = info.listHwnd;
};
}
public bool HideDropDownAfterSelect {
get {
return hideDropDownAfterSelect;
}
set {
if (hideDropDownAfterSelect != value) {
hideDropDownAfterSelect = value;
if (!value) dropDown.AssignHandle(dropDownHandle);
else dropDown.ReleaseHandle();
}
}
}
private class NativeDropDownList : NativeWindow {
public ComboBox ParentControl;
protected override void WndProc(ref Message m) {
if (m.Msg == 0x202) { //WM_LBUTTONUP
AcceptSelection(false);
return;
}
//WM_LBUTTONDBLCLK
if (m.Msg == 0x203) AcceptSelection(true);
base.WndProc(ref m);
}
private void AcceptSelection(bool hideDropDown) {
//LB_GETCURSEL = 0x188
Message m = Message.Create(Handle, 0x188, IntPtr.Zero, IntPtr.Zero);
WndProc(ref m);
int i = m.Result.ToInt32();
typeof(ComboBox).GetMethod("OnSelectedIndexChanged",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.Invoke(ParentControl, new object[] { EventArgs.Empty });
if (i == -1) return;
ParentControl.Text = ParentControl.Items[i].ToString();
ParentControl.SelectAll();
ParentControl.Invalidate();
if (hideDropDown) {
ParentControl.DroppedDown = false;
}
}
}
}
//Usage
customComboBox1.HideDropDownAfterSelect = false;
//You can select the item and hide the drop down by double-clicking left mouse
//It works that way because of the code above at WM_LBUTTONDBLCLK
使用 aListBox
而不是 a ComboBox
。即使在用户选择了一个选项之后,您想要保持 ComboBox 打开的操作将是不寻常和意外的行为。