自定义ComboBox未正确关闭

时间:2013-05-13 18:53:45

标签: c# combobox listbox

我正在尝试使我的自定义ComboBox继承自ContainerControl。我使用this文章作为基础,但重写了它,但我使用了ToolStripControlHost,我自己的自定义ListBox&一个ToolStripDropDown。

现在,ComboBox是一个按钮,您可以在其中单击以显示DropDown包含我的ListBox,在覆盖OnMouseClick时工作正常。

当我尝试关闭DropDown时问题开始,DropDown的'AutoClose'属性为true,如果你点击DropDown外的某个地方(包括按钮),DropDown会关闭......

protected override void OnMouseClick(MouseEventArgs e)
{
    base.OnMouseClick(e);
        /* listboxControl = ToolStripDropDown */
    if (!listboxControl.Visible)
    {
    listboxControl.Show(this, GetDropLocation(), ToolStripDropDownDirection.BelowRight);
            //listbox.Capture = true;
    }
}

这是单击按钮的代码..那么如果单击它会发生什么? 如果显示DropDown,它首先关闭DropDown,然后触发OnMouseClick事件。含义:listboxControl.Visible已经是假的&它会再次显示DropDown。所有这一切都导致了快速关闭。

我一直坚持这个问题已经有一段时间了,谷歌似乎对这个主题知之甚少(关于CodeProject的那篇文章也有同样的错误)。

我尝试过在显示DropDown后禁用AutoClose并捕获鼠标,这部分工作但它会影响我托管的ListBox的工作。 ListBox包含一组控件(项),这些项具有悬停绘画效果。在ListBox控件中捕获鼠标可以防止触发OnMouseEnter。

非常感谢所有输入!

1 个答案:

答案 0 :(得分:1)

当DropDown关闭时,您需要一个变量来跟踪光标位置。

这是一个快速而又脏的示例控件:

public class CustomDropBox : Control {
  private ListBox box = new ListBox() { IntegralHeight = false };
  private ToolStripControlHost host;
  private ToolStripDropDown drop;
  private bool wasShowing = false;

  public CustomDropBox() {
    box.MinimumSize = new Size(120, 120);
    box.MouseUp += box_MouseUp;
    box.KeyPress += box_KeyPress;
    box.Items.AddRange(new string[] { "aaa", "bbb", "ccc" });
    host = new ToolStripControlHost(box) { Padding = Padding.Empty };
    drop = new ToolStripDropDown() { Padding = Padding.Empty };
    drop.Closing += drop_Closing;
    drop.Items.Add(host);
  }

  private Rectangle GetDownRectangle() {
    return new Rectangle(this.ClientSize.Width - 16, 0, 16, this.ClientSize.Height);
  }

  void drop_Closing(object sender, ToolStripDropDownClosingEventArgs e) {
    if (e.CloseReason == ToolStripDropDownCloseReason.AppClicked) {
      wasShowing = GetDownRectangle().Contains(this.PointToClient(Cursor.Position));
    } else {
      wasShowing = false;
    }
  }

  void box_KeyPress(object sender, KeyPressEventArgs e) {
    if (e.KeyChar == (char)Keys.Enter && box.SelectedIndex > -1) {
      drop.Close();
    }
  }

  void box_MouseUp(object sender, MouseEventArgs e) {
    int index = box.IndexFromPoint(e.Location);
    if (index > -1) {
      drop.Close();
    }
  }

  protected override void OnMouseDown(MouseEventArgs e) {
    if (e.Button == MouseButtons.Left && GetDownRectangle().Contains(e.Location)) {
      if (wasShowing) {
        wasShowing = false;
      } else {
        drop.Show(this, new Point(0, this.Height));
      }
    }      
    base.OnMouseDown(e);
  }

  protected override void OnPaint(PaintEventArgs e) {
    e.Graphics.Clear(Color.White);
    ControlPaint.DrawComboButton(e.Graphics, GetDownRectangle(), ButtonState.Normal);
    base.OnPaint(e);
  }
}