Disabling a ComboBox or Listbox item 

There is no API or VCL pre-defined method that can be used to disable an item in a ComboBox or ListBox.  That is, these Standard Controls do not natively support this functionality.  However, the most common approach is to make the control owner-drawn, then render a particular item (or items) in a "disabled" state (i.e., grayed).  A TComboBox can be made owner-drawn via the Style property (set to csOwnerDrawFixed or csOwnerDrawVariable).  Similarly, a TListBox can be made owner-drawn by setting the Style property to lbOwnerDrawFixed or lbOwnerDrawVariable.

In this example, we'll disable the first item in the list of a ComboBox. The method for a ListBox is virtually identical. Note, the TOwnerDrawState does not affect the way items are displayed. It's up to the user to check the state and act accordingly. 
 

KEYWORDS: owner-drawn, OnDrawItem, TexOut, FillRect


 

const int disabled_index = 0;  // first item for example

//---------------------------------------------------------------------------

// (1) Implement a handler for the OnDrawItem event...

void __fastcall TForm1::ComboBox2DrawItem(TWinControl *Control, int Index, 
    TRect &Rect, TOwnerDrawState State)
{
    // eliminate artifacts
    ComboBox2->Canvas->FillRect(Rect);

    // check to see if Index is our "disabled" item
    if (Index == 0)
    {
        // gray out it's text
        ComboBox2->Canvas->Font->Color = clGray;

        // white out the selection rectangle
        if (State.Contains(odSelected))
        {
            ComboBox2->Canvas->Brush->Color = clWhite;
            ComboBox2->Canvas->FillRect(Rect);
        }
    }
    else ComboBox2->Canvas->Font->Color = clBlack;

    ComboBox2->Canvas->TextOut(Rect.Left, Rect.Top, ComboBox2->Items->Strings[Index]);
}
 
 

// (2) If the clicked item is our "disabled" item, keep 
// it from being selected. Use the OnChange event for this task...

void __fastcall TForm1::ComboBox2Change(TObject *Sender)
{
   if (ComboBox2->ItemIndex == 0)
   {
       ComboBox2->ItemIndex = -1;
       ComboBox2->DroppedDown = true;
   }
}

 


 
 

Note that the TStrings::Objects property can be used to store a boolean value indicating the enabled/disabled state of each item.  This approach can be useful for disabling multiple items.