首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ToolStripDropDown在基础控件之前捕获MouseeDown

ToolStripDropDown在基础控件之前捕获MouseeDown
EN

Stack Overflow用户
提问于 2018-09-18 18:06:12
回答 1查看 66关注 0票数 1

我已经创建了自己的ComboBox控件,其中下拉部分包含一棵树。我见过这些解决方案使用普通的ComboBox并覆盖WndProc,但是尽管有大量的代码,但总是有一些奇怪的行为。所以我决定让它变得简单:只是一个带有ToolStripDropDown/ToolStripControlHost的标签,当鼠标在标签上向下时打开它。丢失的ComboBox三角形不疼。

一切都很完美,除了一件小事情:就像股票ComboBox一样,当我再次点击标签时,我想让下拉列表隐藏起来。但是当我点击它时,下拉列表隐藏了一秒,只是为了再次出现。如果我点击标签外面,下拉列表就会隐藏起来,就像它应该隐藏的那样。

代码语言:javascript
复制
public class RepoNodeComboBox: Label
{
    RepoTreeView repoTreeView;
    ToolStripControlHost treeViewHost;
    ToolStripDropDown dropDown;
    bool isDropDownOpen;

    public int DropDownHeight;

    public RepoNodeComboBox()
    {
        repoTreeView = new RepoTreeView();
        repoTreeView.BorderStyle = BorderStyle.None;
        repoTreeView.LabelEdit = false;

        treeViewHost = new ToolStripControlHost(repoTreeView);
        treeViewHost.Margin = Padding.Empty;
        treeViewHost.Padding = Padding.Empty;
        treeViewHost.AutoSize = false;

        dropDown = new ToolStripDropDown();
        dropDown.CanOverflow = true;
        dropDown.AutoClose = true;
        dropDown.DropShadowEnabled = true;
        dropDown.Items.Add(treeViewHost);
        dropDown.Closing += dropDownClosing;

        TextAlign = ContentAlignment.MiddleLeft;
        BackColor = SystemColors.Window;
        BorderStyle = BorderStyle.FixedSingle;

        DropDownHeight = 400;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing) 
        {
            if (dropDown != null) 
            {
                dropDown.Dispose();
                dropDown = null;
            }
        }
        base.Dispose(disposing);
    }

    // when mouse goes down on the label, this is executed first            
    void dropDownClosing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        // just to test if I can get more out of it than with dropdown.Visible
        isDropDownOpen = false; 
    }

    // this is subsidiary to the Closing event of the dropdown
    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (dropDown != null) 
        {
            if (isDropDownOpen)
            {
                dropDown.Hide();
            }
            else
            {
                repoTreeView.Size = new Size(Width, DropDownHeight);
                treeViewHost.Width = Width;
                treeViewHost.Height = DropDownHeight;
                dropDown.Show(this, 0, Height);
                isDropDownOpen = true;
            }
        }

        base.OnMouseDown(e);
    }
}

据我所见(断点),下拉列表首先捕获鼠标向下事件,以便关闭自身。只有在此之后,我的标签才会通过MOUSEDOWN事件传递,并且由于它看到下拉列表被关闭,它认为标签是第一次被点击--然后再次打开下拉列表。

因此,标签似乎没有机会知道鼠标向下是否是关闭下拉项目的结果。我可以打开它的每一个其他事件,但这将不需要其他关闭事件发生。

有什么方法可以确保一个打开的下拉项目只是关闭,即使我点击标签?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-18 19:23:09

当浮动主机关闭时,尝试检查鼠标位置:

代码语言:javascript
复制
void dropDownClosing(object sender, CancelEventArgs e) {
  isDropDownOpen = this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition));
}

在MouseDown代码中,确保在true块中将isDropDownOpen设置为false:

代码语言:javascript
复制
protected override void OnMouseDown(MouseEventArgs e) {
  if (dropDown != null) {
    if (isDropDownOpen) {
      isDropDownOpen = false;
      dropDown.Hide();
    } else {
      isDropDownOpen = true;
      repoTreeView.Size = new Size(Width, DropDownHeight);
      treeViewHost.Width = Width;
      treeViewHost.Height = DropDownHeight;
      dropDown.Show(this, 0, Height);
    }
  }
  base.OnMouseDown(e);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52392320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档