我有一个类似以下的ComboBox,并希望在点击标题部分时阻止它关闭(例如 管理员 )。
我刚试过以下代码。
private void cmboName_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmboName.SelectedIndex == 1)
{
cmboName.DroppedDown = true;
return;
}
}
但是有一种颤抖的发生;第一个组合框将关闭然后打开。
答案 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();
}
}
这不是你想要的,但它是下一个最好的东西。