65.9K
CodeProject is changing. Read more.
Home

Read only ComboBox

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.37/5 (26 votes)

Mar 9, 2004

viewsIcon

237959

downloadIcon

1671

How to make ComboBox read only

Introduction

Surprisingly the MS Visual Studio ComboBox doesn’t have such an important property: ReadOnly. After searching on internet for solving this problem and not finding a relevant resolution I decided to add this important property to a new ComboBox control.

Using the code

Create a new derived class from ComboBox:

public class NewComboBox    : System.Windows.Forms.ComboBox

Declare private variables:

private bool readOnly;
private Color tBackColor;
private Color tForeColor;
private ContextMenu cmnuEmpty;
private ComboBoxStyle dropDownStyle = ComboBoxStyle.DropDown;
private Color readOnlyBackColor = SystemColors.Control;
private Color readOnlyForeColor = SystemColors.WindowText;

Set custom context menu to be display when read only:

public ReadOnlyComboBox()
{
  cmnuEmpty = new ContextMenu(); //code this menu for your needs
}

Declare ReadOnly property:

public bool ReadOnly
{
  get 
  {
    return readOnly;
  }
  set
  {
    if(readOnly != value)
    {
      readOnly = value;
      if(value)
      {
        this.ContextMenu = cmnuEmpty;
        base.DropDownStyle = ComboBoxStyle.Simple;
        base.Height = 21;
        this.tBackColor = this.BackColor;
        this.tForeColor = this.ForeColor;
        base.BackColor = this.ReadOnlyBackColor;
        base.ForeColor = this.ReadOnlyForeColor;
      }
      else
      {
        this.ContextMenu = null;
        base.DropDownStyle = dropDownStyle;
        base.BackColor = tBackColor;
        base.ForeColor = tForeColor;
      }
    }
  }
}

Override OnKeyDown and OnKeyPress events to stop editing when readonly:

 
protected override void OnKeyDown(KeyEventArgs e)  
{ 
  if(this.ReadOnly && (
    e.KeyCode == Keys.Up  || 
    e.KeyCode == Keys.Down  ||
    e.KeyCode == Keys.Delete))
    e.Handled = true;
  else
    base.OnKeyDown (e);
}

protected override void OnKeyPress(KeyPressEventArgs e) 
{
    if(this.ReadOnly) 
        e.Handled = true;
    else
        base.OnKeyPress (e);
}

Change the DropDownStyle property to reflect property changes only when not ReadOnly:

new public ComboBoxStyle DropDownStyle
{
  get
  {
    return dropDownStyle;
  }
  set
  {
    if(dropDownStyle != value)
    {
      dropDownStyle = value;
      if(!this.ReadOnly) base.DropDownStyle = value;
    }
  }
}

Add back/fore color properties to reflect changes in ReadOnly property:

public Color ReadOnlyBackColor
{
  get
  {
    return readOnlyBackColor;
  }
  set
  {
    readOnlyBackColor = value;
  }
}
    
public Color ReadOnlyForeColor
{
  get
  {
    return readOnlyForeColor;
  }
  set
  {
    readOnlyForeColor = value;
  }
}

ToDo

Eliminate the white border that appears inside the client area when enable XP styles and BackColor is not default color.