C# 禁用组合框中的特定项
我有一个WinForms应用程序,我想知道是否有一种更优雅的方法可以在不更改SelectedIndex属性-1的情况下禁用Combobox项 我一直在谷歌上搜索,很多解决方案都涉及ASP.Net下拉列表,但这看起来很有希望。我想我可能必须建立自己的组合框控件,但在我重新发明轮子之前,我想我会在这里问一下这是否可能 更新 这是最终的解决方案,多亏了Arif Eqbal:C# 禁用组合框中的特定项,c#,winforms,combobox,C#,Winforms,Combobox,我有一个WinForms应用程序,我想知道是否有一种更优雅的方法可以在不更改SelectedIndex属性-1的情况下禁用Combobox项 我一直在谷歌上搜索,很多解决方案都涉及ASP.Net下拉列表,但这看起来很有希望。我想我可能必须建立自己的组合框控件,但在我重新发明轮子之前,我想我会在这里问一下这是否可能 更新 这是最终的解决方案,多亏了Arif Eqbal: //Add a Combobox to a form and name it comboBox1 // using Sy
//Add a Combobox to a form and name it comboBox1
//
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
this.comboBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem);
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
}
private void Form1_Load(object sender, EventArgs e)
{
this.comboBox1.Items.Add("Test1");
this.comboBox1.Items.Add("Test2");
this.comboBox1.Items.Add("Test3");
this.comboBox1.Items.Add("Test4");
this.comboBox1.Items.Add("Test5");
this.comboBox1.Items.Add("Test6");
this.comboBox1.Items.Add("Test7");
}
Font myFont = new Font("Aerial", 10, FontStyle.Underline|FontStyle.Regular);
Font myFont2 = new Font("Aerial", 10, FontStyle.Italic|FontStyle.Strikeout);
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index == 1 || e.Index == 4 || e.Index == 5)//We are disabling item based on Index, you can have your logic here
{
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), myFont2, Brushes.LightSlateGray, e.Bounds);
}
else
{
e.DrawBackground();
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), myFont, Brushes.Black, e.Bounds);
e.DrawFocusRectangle();
}
}
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 1 || comboBox1.SelectedIndex == 4 || comboBox1.SelectedIndex == 5)
comboBox1.SelectedIndex = -1;
}
}
}
试试这个。。。它是否符合您的目的: 我假设您有一个名为
ComboBox1
的组合框,您想禁用第二项,即索引为1的项
将组合框的DrawMode
属性设置为OwnerDrawFixed
,然后按如下所示处理这两个事件:
Font myFont = new Font("Aerial", 10, FontStyle.Regular);
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index == 1) //We are disabling item based on Index, you can have your logic here
{
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), myFont, Brushes.LightGray, e.Bounds);
}
else
{
e.DrawBackground();
e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), myFont, Brushes.Black, e.Bounds);
e.DrawFocusRectangle();
}
}
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 1)
comboBox1.SelectedIndex = -1;
}
以下是我100%基于Arif Eqbal的答案。 改善措施包括:
- 重新使用组合框中的
,而不是创建新字体(这样,如果在设计器中更改字体,就不必更新代码)字体
- 重新使用默认的
(因此它应该与您的主题相匹配;但是,如果您手动更改组合框中使用的颜色,它将不起作用)systembrush
- 对于禁用的项目,我必须重新绘制背景,否则每次重新绘制灰色项目时,它们的颜色会越来越接近黑色
- 创建专用的
方法以避免复制/粘贴IsItemDisabled
这是进一步的修改。上述解决方案的问题是,所选项目不可见,因为字体前景和背景选择都是黑色的。因此,应根据
e.State
的值设置字体:
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (e.Index >= 0)
{
if (IsItemDisabled(e.Index))
{
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
e.Graphics.DrawString(comboBox.Items[e.Index].ToString(), comboBox.Font, Brushes.LightSlateGray, e.Bounds);
}
else
{
e.DrawBackground();
// Set the brush according to whether the item is selected or not
Brush br = ( (e.State & DrawItemState.Selected) > 0) ? SystemBrushes.HighlightText : SystemBrushes.ControlText;
e.Graphics.DrawString(comboBox.Items[e.Index].ToString(), comboBox.Font, br, e.Bounds);
e.DrawFocusRectangle();
}
}
}
ASP.NET!=WinForms,别看那里。扩展基本组合框并不难(通常是添加复选框、图标等),但我认为没有任何这样的标准支持。如果你真的想让用户感觉到该项被禁用,那么你提到的链接就是一种方法。您可能希望将文本绘制为灰色,您可能希望不显示选择背景色等等,当然用户仍然可以选择该项目,因此您当然需要处理selectedIndex更改并将selectedIndex设置为-1。但是做这个练习在视觉上会更具启发性。@cool\u php我已经有一段时间没有使用那个代码了。代码开头的注释是否足够(即使用
OwnerDrawFixed
)?
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (e.Index >= 0)
{
if (IsItemDisabled(e.Index))
{
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
e.Graphics.DrawString(comboBox.Items[e.Index].ToString(), comboBox.Font, Brushes.LightSlateGray, e.Bounds);
}
else
{
e.DrawBackground();
// Set the brush according to whether the item is selected or not
Brush br = ( (e.State & DrawItemState.Selected) > 0) ? SystemBrushes.HighlightText : SystemBrushes.ControlText;
e.Graphics.DrawString(comboBox.Items[e.Index].ToString(), comboBox.Font, br, e.Bounds);
e.DrawFocusRectangle();
}
}
}