繁体   English   中英

如何强制DropDownList样式ComboBox仅在用户单击下拉按钮时打开?

[英]How can I force a DropDownList style ComboBox to only open when the user clicks the drop-down button?

在C#.NET 2.0中,我有一个带有ComboBoxStyle DropDownList的WinForms ComboBox。 但是,只要用户单击组合框中的任何位置,就会显示下拉列表。 相反,我想只在用户明确点击下拉按钮时才打开它。 当用户点击组合框的其余部分时,我只想为其分配键盘焦点,以便他或她可以在所选项目上使用某些键盘命令。 最好的方法是什么?

在得到其他答案的一些帮助之后,我得出了这个快速的解决方案:

public class MyComboBox : ComboBox
{
    public MyComboBox()
    {
        FlatStyle = FlatStyle.Popup;
        DropDownStyle = ComboBoxStyle.DropDownList;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0201 /* WM_LBUTTONDOWN */ || m.Msg == 0x0203 /* WM_LBUTTONDBLCLK */)
        {
            int x = m.LParam.ToInt32() & 0xFFFF;
            if (x >= Width - SystemInformation.VerticalScrollBarWidth)
                base.WndProc(ref m);
            else
            {
                Focus();
                Invalidate();
            }
        }
        else
            base.WndProc(ref m);
    }
}

您有两个需要考虑的问题。 第一个是相当简单的:确定是否应该打开或关闭下拉列表。 这段代码可以这样做:

    void comboBox1_MouseClick(object sender, MouseEventArgs e)
    {
        ComboBox combo = sender as ComboBox;
        int left = combo.Width - (SystemInformation.HorizontalScrollBarThumbWidth + SystemInformation.HorizontalResizeBorderThickness);
        if (e.X >= left)
        {
            // They did click the button, so let it happen.
        }
        else
        {
            // They didn't click the button, so prevent the dropdown.
        }
    }

第二个问题更为重要 - 实际上阻止了下拉的出现。 最简单的方法是:

comboBox1.DropDownStyle = ComboBoxStyle.DropDown;

但是,这允许输入您可能不想要的框。

我花了大约15分钟来查看选项,看起来为了防止下拉列表出现并同时阻止用户输入下拉列表,您需要对控件进行子类化。 这样,你可以覆盖OnMouseClick(),只有当他们点击按钮时才调用base.OnMouseClick()。 它看起来像这样(未经测试):

public class CustomComboBox : ComboBox
{
    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        int left = this.Width - (SystemInformation.HorizontalScrollBarThumbWidth + SystemInformation.HorizontalResizeBorderThickness);
        if (e.X >= left)
        {
            // They did click the button, so let it happen.
            base.OnMouseClick(e);
        }
        else
        {
            // They didn't click the button, so prevent the dropdown.
            // Just do nothing.
        }
    }
}

您可以获得鼠标单击的X,Y位置,如果不在下拉“图标”(由于缺少更好的单词),您可以从那里强制折叠。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM