我有一个自定义WinForms用户控件,看起来像一个组合框,但是打开一个ToolStripDropDown,它包含另一个名为NumericFilterPanel的自定义用户控件,它有一个复选框,一个组合框和一个文本框。
问题在于,当用户单击选择嵌入在下拉控件中的组合框的选项时,会导致父下拉隐藏。
我设置了ToolStripDropDown.AutoClose = false,它修复了原始问题,但现在我很难检测到下拉列表失去焦点的所有情况,例如当用户点击父窗体或切换程序时。有时下拉列表仍然可见且最顶层。
有没有办法保持AutoClose = true并阻止嵌入式组合框关闭父下拉列表,还是有办法始终检测下拉列表何时失去焦点,以便我可以手动关闭它?
using System;
using System.Drawing;
using System.Windows.Forms;
namespace mviWinControls
{
public partial class NumericRangeDropDown : UserControl
{
private const int ARROW_HEIGHT = 4;
private Brush arrowBrush = new SolidBrush(Color.FromArgb(77, 97, 133));
private ToolStripDropDown _dropdown;
private ToolStripControlHost _host;
private NumericFilterPanel _filter;
public NumericRangeDropDown()
{
InitializeComponent();
_filter = new NumericFilterPanel();
_filter.DropDown = this;
_host = new ToolStripControlHost(_filter);
_host.Margin = Padding.Empty;
_host.Padding = Padding.Empty;
_dropdown = new ToolStripDropDown();
_dropdown.Margin = Padding.Empty;
_dropdown.Padding = Padding.Empty;
_dropdown.AutoClose = false; // Use this because panel has a combobox. https://social.msdn.microsoft.com/Forums/windows/en-US/dd95b982-820e-4807-8a1f-79c74acab3f8/two-problems-toolstripdropdown?forum=winforms
_dropdown.Items.Add(_host);
_dropdown.Leave += new System.EventHandler(this.DropDown_Leave);
this.Leave += new System.EventHandler(this.DropDown_Leave);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null) components.Dispose();
if (_dropdown != null) _dropdown.Dispose();
}
base.Dispose(disposing);
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
_filter.SetValue(value);
}
}
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e);
TextBox _txtDraw = new TextBox();
_txtDraw.Width = this.Width;
using (Bitmap bmp = new Bitmap(_txtDraw.Width, _txtDraw.Height))
{
_txtDraw.DrawToBitmap(bmp, new Rectangle(0, 0, _txtDraw.Width, _txtDraw.Height));
e.Graphics.DrawImage(bmp, 0, 0);
}
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Near;
format.FormatFlags = StringFormatFlags.NoWrap;
format.LineAlignment = StringAlignment.Center;
using (Brush b = new SolidBrush(this.ForeColor))
e.Graphics.DrawString(this.Text, this.Font, b, this.DisplayRectangle, format);
Point[] arrowPoints = new Point[] { new Point(this.Width - ARROW_HEIGHT * 3 - 2, (this.Height - ARROW_HEIGHT) / 2),
new Point(this.Width - ARROW_HEIGHT + 1 - 2, (this.Height - ARROW_HEIGHT) / 2),
new Point(this.Width - ARROW_HEIGHT * 2 - 2, this.Height - (this.Height - ARROW_HEIGHT) / 2) };
e.Graphics.FillPolygon(arrowBrush, arrowPoints );
}
private void DropDown_Leave(object sender, EventArgs e)
{
HideDropDown();
this.Text = _filter.SummaryText();
}
private void NumericRangeDropDown_Click(object sender, EventArgs e)
{
if (_dropdown.Visible)
HideDropDown();
else
ShowDropDown();
}
public void ShowDropDown()
{
_dropdown.Show(this, new Point(0, this.Height), ToolStripDropDownDirection.Default);
_dropdown.BringToFront();
//_dropdown.Focus();
_filter.Select();
_filter.Focus();
}
public void HideDropDown()
{
_dropdown.Close();
this.Invalidate();
}
}
}
答案 0 :(得分:1)
这是一个组合框,可以自动为您禁用和启用主机控件上的AutoClose属性。
来源(我在示例中将其修改为组合框,而不是DatePicker):http://www.queasy.me/programming/questions/13919634/tool+strip+toolstripdropdownbutton+close+and+lose+window+focus
public partial class CComboBox : ComboBox
{
private bool savedAutoClose;
public CComboBox()
{
InitializeComponent();
}
protected override void OnDropDownClosed(EventArgs e)
{
if (this.Parent != null)
{
var dropDownHost = this.Parent.Parent as ToolStripDropDown; // recursive instead?
if (dropDownHost != null)
dropDownHost.AutoClose = savedAutoClose; // restore the parent's AutoClose preference
}
base.OnDropDownClosed(e);
}
protected override void OnDropDown(EventArgs e)
{
if (this.Parent != null)
{
var dropDownHost = this.Parent.Parent as ToolStripDropDown; // recursive instead?
if (dropDownHost != null)
{
savedAutoClose = dropDownHost.AutoClose;
// ensure that our parent doesn't close while the calendar is open
dropDownHost.AutoClose = false;
}
}
base.OnDropDown(e);
}
}