如何在选择项目时阻止关闭组合框

时间:2016-05-19 09:53:28

标签: c# winforms

我有一个类似以下的ComboBox,并希望在点击标题部分时阻止它关闭(例如 管理员 )。

enter image description here

我刚试过以下代码。

private void cmboName_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (cmboName.SelectedIndex == 1)
        {
            cmboName.DroppedDown = true;
            return;
        }
    }

但是有一种颤抖的发生;第一个组合框将关闭然后打开。

2 个答案:

答案 0 :(得分:0)

更新

您需要做的是禁止告诉系统ComboBox想要关闭下拉列表的消息。

要做到这一点,你需要创建一个子类:

public partial class myComboBox : ComboBox
{
    public myComboBox()
    {
        InitializeComponent();
    }

    private int direction = 0;  // where to jump when when doing keyboard selection
    private int lastIndex = -1;

    private void skip()
    {
        if (direction > 0 && (SelectedIndex + 1 < Items.Count))
            SelectedIndex += 1;
        else if (direction < 0 && (SelectedIndex - 1 >= 0))
            SelectedIndex -= 1;
        else SelectedIndex = lastIndex;

    }

    // optional, but you are owner-drawing anyway..
    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }

    // use your own logic to determine which entries can be selected!
    bool Invalid(int index)
    {
        return index < 0 ? true 
                         : (Items[index].ToString().StartsWith("X"));
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Up) direction = -1;
        else if (e.KeyCode == Keys.Down) direction = 1;
        else direction = 0;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x111) /*  WM_COMMAND */
        {
            if (((int)m.WParam >> 16) == 1)
            {
                if (Invalid(SelectedIndex))
                {
                    while (Invalid(SelectedIndex)) skip();  // skip invalid entries
                    m.Result = new IntPtr(1); // return success
                    return;                   // consume the message
                }
                lastIndex = SelectedIndex;
            }
        }
        base.WndProc(ref m);
    }

  }
}

请注意,我的测试使用了对无效/不可选分组/标题项的简单检查。而不是检查内容是否为“X”,你需要使用适合自己的检查!可能与ItemDraw事件中用于加粗这些项目的条件相同。

答案 1 :(得分:0)

一种解决方案是从选择中禁用某些项目 试试这个:

private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
        }

 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string itemText = comboBox1.GetItemText(comboBox1.SelectedItem);

            if ((itemText == "Admins") || (itemText == "Users"))            
                comboBox1.SelectedIndex = -1;
        }

private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            string itemText = comboBox1.GetItemText(comboBox1.Items[e.Index]);

            if ((itemText == "Admins") || (itemText == "Users"))
            {
                using (var f = new Font("Microsoft Sans Serif", 8, FontStyle.Bold))
                    e.Graphics.DrawString(itemText, f, Brushes.Black, e.Bounds);
            }
            else
            {
                e.DrawBackground();

                using (var f = new Font("Microsoft Sans Serif", 8, FontStyle.Regular))
                    e.Graphics.DrawString(itemText, f, Brushes.Black, e.Bounds);

                e.DrawFocusRectangle();
            }
        }

这不是你想要的,但它是下一个最好的东西。