Search code examples
c#winformscombobox

Disabling particular Items in a Combobox


I have a WinForms App and I was wondering if there was a more elegant way of disabling Combobox item without changing the SelectedIndex property -1 for all disabled values.

I have been googling and a lot of the solutions involve ASP.Net DropDownLists but this LINK looks promising. I think I may have to build my own ComboBox control but before I re-invent the wheel I figure I would ask here if it was possible.

UPDATE

Here is the final solution, thanks to Arif Eqbal:

//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;
            }
        }
    }

Solution

  • Try this... Does it serve your purpose:

    I assume you have a ComboBox called comboBox1 and you want to disable the second item i.e. an item with index 1.

    Set the DrawMode property of the combobox to OwnerDrawFixed then handle these two events as shown below:

    Font myFont = new Font("Arial", 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;
    }