private void ShowDropDown() { var rect = RectangleToScreen(ClientRectangle); var location = new Point(rect.X, rect.Y + Height); _dropDownControl.Size = new Size(rect.Width, _checkedListBox.Items.Count * _checkedListBox.ItemHeight + ScreenHelpers.ScaleByCurrentDPI(5)); _dropDownControl.Show(location); _dropDownClosing = true; _dropDownControl.Focus(); }
///<summary></summary> ///<param name="keepMenuOpen">An open to keep the drop down menu open if the main window is no longer the active window.</param> public ToolStripDropDownAttacher(ToolStripDropDown menu, Control c, bool keepMenuOpen = true) { Menu = menu; Control = c; KeepMenuOpen = keepMenuOpen; menu.AutoClose = false; menu.Click += delegate { isFocusing = true; menu.Focus(); IntPtr h = GetTopWindow(c.Handle); // after the main window is minimized and restored, clicking on // clock will deactivate the main window title bar unless this is called: SendMessage(h, WM_NCACTIVATE, (IntPtr)1, (IntPtr)0); isFocusing = false; }; menu.Closing += (o, e) => { if (isClosing) { e.Cancel = false; } }; menu.KeyDown += (o, e) => { if (e.KeyCode == Keys.Escape && !menu.AutoClose) { CloseMenu(ToolStripDropDownCloseReason.Keyboard); e.Handled = true; //e.SuppressKeyPress = true; } }; menu.GotFocus += delegate { // click on the control, then tab to focus on the drop down // then minimize the main window, then restore the main window // tabbing into the drop down deactivates the main window var tl = GetTopWindow(c.Handle); SendMessage(tl, WM_NCACTIVATE, (IntPtr)1, (IntPtr)0); }; menu.LostFocus += delegate { // if another window is clicked, then two issues occur: // 1) The top level window doesn't deactivate, so two windows on the // desktop both appear active. // 2) When the focus returns to this program's main window, clicking // on thedrop down shows this window's caption as deactivated. if (!c.Focused && !isFocusing && !isClosing) { if (KeepMenuOpen) { IntPtr fg = GetForegroundWindow(); IntPtr tl = GetTopWindow(c.Handle); bool b = fg == tl; if (!b) { SendMessage(tl, WM_NCACTIVATE, (IntPtr)0, (IntPtr)0); return; } } CloseMenu(ToolStripDropDownCloseReason.CloseCalled); } }; c.MouseDown += delegate { ShowMenu(); }; /* * Removing this help preventing menu showing on Tab or windows focus change * by: Awais Ahmad Alvi * * c.GotFocus += delegate { * if (!menu.Visible && !isClosing) * ShowMenu(); * }; * */ c.LostFocus += delegate { // if the focus was transferred to another window, then keep // the drop down open. Otherwise if the focus was transfered to // another control in the same window then close the menu bool b = true; if (KeepMenuOpen) { IntPtr fg = GetForegroundWindow(); IntPtr tl = GetTopWindow(c.Handle); b = tl == fg; } if (!menu.Focused && b) { CloseMenu(ToolStripDropDownCloseReason.CloseCalled); } }; c.KeyDown += (o, e) => { if (e.KeyData == Keys.Escape) { e.Handled = true; e.SuppressKeyPress = true; // stops the beep if (menu.Visible) { CloseMenu(ToolStripDropDownCloseReason.Keyboard); } } }; c.EnabledChanged += delegate { menu.Enabled = c.Enabled; }; Application.AddMessageFilter(this); }