해결책을 찾았습니다. ToolStripManager 코드 (감사합니다 ReSharper!)를 보면 AutoClose가 true로 설정된 경우 관리자가 사용자가 드롭 다운 바깥을 클릭 할 때를 감지하기 위해 응용 프로그램 메시지를 모니터링하고 있음을 발견했습니다.
class MyComboBox : ComboBox, IMessageFilter
{
private ToolStripDropDown m_dropDown;
MyComboBox()
{
...
Application.AddMessageFilter(this);
...
}
protected override void Dispose(bool disposing)
{
...
Application.RemoveMessageFilter(this);
base.Dispose(disposing);
}
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_RBUTTONDOWN = 0x0204;
private const int WM_MBUTTONDOWN = 0x0207;
private const int WM_NCLBUTTONDOWN = 0x00A1;
private const int WM_NCRBUTTONDOWN = 0x00A4;
private const int WM_NCMBUTTONDOWN = 0x00A7;
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[ResourceExposure(ResourceScope.None)]
public static extern int MapWindowPoints(IntPtr hWndFrom, IntPtr hWndTo, [In, Out] ref Point pt, int cPoints);
public bool PreFilterMessage(ref Message m)
{
if (m_dropDown.Visible)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
//
// When a mouse button is pressed, we should determine if it is within the client coordinates
// of the active dropdown. If not, we should dismiss it.
//
int i = unchecked((int)(long)m.LParam);
short x = (short)(i & 0xFFFF);
short y = (short)((i >> 16) & 0xffff);
Point pt = new Point(x, y);
MapWindowPoints(m.HWnd, m_dropDown.Handle, ref pt, 1);
if (!m_dropDown.ClientRectangle.Contains(pt))
{
// the user has clicked outside the dropdown
pt = new Point(x, y);
MapWindowPoints(m.HWnd, Handle, ref pt, 1);
if (!ClientRectangle.Contains(pt))
{
// the user has clicked outside the combo
hideDropDown();
}
}
break;
}
}
return false;
}
}
흠, 어쩌면 당신은 또한 초점을 제어하거나 – DJmRek
내가 그것을 시도했습니다 (윈폼은이 같은) 당신의 콤보 상자에 대한 "KeyPreview"를 만들 수 있지만 그렇지 않습니다 : 나는 다음과 같은 방법으로 자신의 코드를 적용했습니다 작업. 나는 또한 모든 WM_KEYDOWN, WM_KEYUP, WM_CHAR 메시지를 캡쳐하여 드롭 다운으로 보내고 (SendMessage를 사용하여) 콤보의 편집 컨트롤로 다시 보냈지 만 작동하지 않습니다. –
정말 간단하고 어쩌면 더러운 해결책이 있습니다 :'ComboBox.LostFocus -> Toolstripdropdown.Close()'는 작동하지만 아직 테스트하지 않았습니다. 간단한 "AutoClose"라고 생각합니다. – DJmRek