C# 如何防止在选择项目时关闭组合框
我有一个如下所示的组合框,希望在单击标题部分时阻止它关闭(例如,Administrators) 我只是尝试了以下代码C# 如何防止在选择项目时关闭组合框,c#,winforms,C#,Winforms,我有一个如下所示的组合框,希望在单击标题部分时阻止它关闭(例如,Administrators) 我只是尝试了以下代码 private void cmboName_SelectedIndexChanged(object sender, EventArgs e) { if (cmboName.SelectedIndex == 1) { cmboName.DroppedDown = true; return;
private void cmboName_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmboName.SelectedIndex == 1)
{
cmboName.DroppedDown = true;
return;
}
}
但是有一种颤抖发生了;第一个组合框将关闭,然后打开。更新 您需要做的是抑制消息,该消息告诉系统,
组合框
希望在不应该关闭下拉列表时关闭下拉列表
为此,您需要创建一个子类:
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);
}
}
}
public部分类myComboBox:ComboBox
{
公共邮箱()
{
初始化组件();
}
private int direction=0;//选择键盘时跳转到哪里
private int lastIndex=-1;
私有void skip()
{
如果(方向>0&(选择的索引+1<项目数))
选择的索引+=1;
否则如果(方向<0&(选择的索引-1>=0))
选择的索引-=1;
else SelectedIndex=最后一个索引;
}
//可选,但您仍然是图纸的所有者。。
受保护的覆盖无效OnPaint(PaintEventArgs pe)
{
基础漆(pe);
}
//使用您自己的逻辑来确定可以选择哪些条目!
bool无效(整数索引)
{
返回指数<0?为真
:(Items[index].ToString().StartsWith(“X”);
}
受保护的覆盖无效OnKeyDown(KeyEventArgs e)
{
如果(e.KeyCode==Keys.Up)方向=-1;
如果(e.KeyCode==Keys.Down)方向=1,则为else;
else方向=0;
}
受保护的覆盖无效WndProc(参考消息m)
{
如果(m.Msg==0x111)/*WM_命令*/
{
if(((int)m.WParam>>16)==1)
{
如果(无效(已选择索引))
{
while(Invalid(SelectedIndex))skip();//跳过无效条目
m、 Result=newintptr(1);//返回成功
return;//使用消息
}
lastIndex=选定的索引;
}
}
基准WndProc(参考m);
}
}
}
注意,我的测试使用一个简单的检查来检查无效/不可选择的分组/标题项。您需要使用自己的适当检查,而不是检查内容是否为“X”!可能与您在
ItemDraw
事件中粗体显示这些项目时使用的条件相同。更新
您需要做的是抑制消息,该消息告诉系统,组合框
希望在不应该关闭下拉列表时关闭下拉列表
为此,您需要创建一个子类:
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);
}
}
}
public部分类myComboBox:ComboBox
{
公共邮箱()
{
初始化组件();
}
private int direction=0;//选择键盘时跳转到哪里
private int lastIndex=-1;
私有void skip()
{
如果(方向>0&(选择的索引+1<项目数))
选择的索引+=1;
否则如果(方向<0&(选择的索引-1>=0))
选择的索引-=1;
else SelectedIndex=最后一个索引;
}
//可选,但您仍然是图纸的所有者。。
受保护的覆盖无效OnPaint(PaintEventArgs pe)
{
基础漆(pe);
}
//使用您自己的逻辑来确定可以选择哪些条目!
bool无效(整数索引)
{
返回指数<0?为真
:(Items[index].ToString().StartsWith(“X”);
}
受保护的覆盖无效OnKeyDown(KeyEventArgs e)
{
如果(e.KeyCode==Keys.Up)方向=-1;
如果(e.KeyCode==Keys.Down)方向=1,则为else;
else方向=0;
}
受保护的覆盖无效WndProc(参考消息m)
{
如果(m.Msg==0x111)/*WM_命令*/
{
if(((int)m.WParam>>16)==1)
{
如果(无效(已选择索引))
{
while(Invalid(SelectedIndex))skip();//跳过无效条目
m、 Result=newintptr(1);//返回成功
return;//使用消息
}
lastIndex=选定的索引;
}
}
基准WndProc(参考m);
}
}
}
注意,我的测试使用一个简单的检查来检查无效/不可选择的分组/标题项。您需要使用自己的适当检查,而不是检查内容是否为“X”!可能与您在
ItemDraw
事件中粗体显示这些项目时使用的条件相同。一种解决方案是从选择中禁用某些项目。试试这个:
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();
}
}
这不是你想要的,但它是下一个最好的选择。一个解决方案是禁止选择某些项目。
试试这个:
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();
}
}
这不是你想要的,但它是下一个最好的东西。你使用的是什么UI框架?WinForms或WPF?使用附加信息更新问题,而不仅仅是将其添加到注释中。您为什么希望在选择项目后阻止其关闭?这似乎是一个糟糕的UI设计好的设计应该是跳过分组项,因为我对标题部分什么都不做。它仅用于对字段进行分类。单击标题部分时,我不想关闭下拉列表。您使用的是什么UI框架?WinForms或WPF?使用附加信息更新问题,而不仅仅是将其添加到注释中。您为什么希望在选择项目后阻止其关闭?这似乎是一个糟糕的UI设计好的设计应该是跳过分组项,因为我对标题部分什么都不做。它仅用于对字段进行分类。单击标题部分时,我不想关闭下拉列表。选择更改事件中的代码与我的代码中的代码相同。是否有可能在没有任何干扰的情况下维持列表视图?这就是我在最后一句话中的意思。I h