【问题标题】:Custom ComboBox not closing properly自定义组合框未正确关闭
【发布时间】:2013-05-13 18:53:44
【问题描述】:

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

现在 ComboBox 是一个按钮,您单击该按钮以显示包含我的 ListBox 的 DropDown,可以很好地覆盖 OnMouseClick。

当我尝试关闭 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 上的那篇文章也有同样的错误)。

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

所有输入将不胜感激!

【问题讨论】:

    标签: c# combobox listbox


    【解决方案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);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多