Click here to Skip to main content
11,479,170 members (60,468 online)
Click here to Skip to main content

ComboBox with read only behavior

, 25 Apr 2005 CPOL 281.3K 3.5K 62
Rate this:
Please Sign up or sign in to vote.
An article about developing a ComboBox with the same read only functionality as the TextBox.

Contents

Introduction

ReadReadOnly behavior of the TextBox

TextBox controls have the nice read only feature. When you set the ReadOnly property of a TextBox to true, you can't edit the text in the TextBox anymore. The user can still select the text and copy it to another place. The background of the TextBox is painted gray so the user has a visual indication of the ReadOnly mode. The text is still painted in black, as in a normal editable TextBox.

This behavior is completely different to Enabled = false. Via the Enabled property, you can completely disable the TextBox. The text is not painted in good readable black anymore but in a gray color. And you can't select the text anymore.

Read only mode of TextBox

The ReadOnly mode is very usable. I often use it, when I have a form with several controls where the user can edit the content of controls depending on his privileges. If the user doesn't have the required privileges, I do not disable the controls but set them to ReadOnly. This way, the user can still very well read the texts in the TextBoxes, because their text is still painted in black.

No ReadOnly property for ComboBoxes

Most other .NET controls don't have a ReadOnly property. So if you want them to be read only, you have to disable them (Enabled = false). What I wanted was a ComboBox that offers a ReadOnly property and mimics the read only behavior of the TextBox. Especially, paint the text in good readable black instead of the disabled color gray.

DropDown Styles

Several people on the net argue, you don't need a ReadOnlyComboBox, because a ComboBox is read only when you set the DropDownStyle of the ComboBox to DropDownList. Well, of course, doing this, the user cannot edit the text in the ComboBox anymore. But he can still select a value from the ComboBox. For me, that's not the same thing as ReadOnly.

Solution

Idea

I tried different things like hooking into the WndProc to capture all the keyboard and mouse events and handle them myself, if the ComboBox is ReadOnly. But it just did not work out. I'm sure I did something wrong, but anyway. I'd also had to do the painting myself, where I had some problems as well.

Finally, I came up with a completely different idea. Whenever the ComboBox is set to ReadOnly = true, I display a TextBox instead that is read only. Because when it's read only, I don't need the dropdown button at all so a TextBox fits everything needed here.

Read only mode of ComboBox

Implementation

Basics

I found two implementation possibilities:

User control decorating the ComboBox and the TextBox

I could have created a new user control having a ComboBox and a TextBox at the same position. The user control acts as a decorator to the two embedded controls, and depending on the ReadOnly property, acts as a TextBox or a ComboBox.

I decided not to do that. Why should I do all the work to decorate the ComboBox? So I came up with solution two:

Inherit from ComboBox and just decorate the TextBox

I create a new control (ReadOnlyComboBox) that inherits from the standard ComboBox control and contains a TextBox. Whenever the ReadOnlyComboBox is set to read only, it acts as a decorator for the embedded TextBox and displays the TextBox instead of the ComboBox.

ReadOnly

First, I added a new property ReadOnly that handles the read only state.

public bool ReadOnly
{
  get { return _isReadOnly; }
  set
  {
    if (value != _isReadOnly)
    { 
      _isReadOnly = value;

      ShowControl();
    }
  }
}

The ShowControl() method is responsible to show either the ComboBox or the TextBox depending on the ReadOnly and the Enabled properties.

private void ShowControl()
{
  if (_isReadOnly)
  {
    _textbox.Visible = _visible && this.Enabled;
    base.Visible = _visible && !this.Enabled;
    _textbox.Text = this.Text;
  }
  else
  {
    _textbox.Visible = false;
    base.Visible = _visible;
  }
}

Visible

The ComboBox already has a Visible property. But we have to implement our own Visible property to store the control's visibility. The reason is simple: when we use the ReadOnly property, we change the visibility of the ComboBox. Thus the Visible property of the ComboBox does not correspond to the visibility of the ReadOnlyComboBox. That's why I declare a new Visible property that hides the original Visible property of the ComboBox.

public new bool Visible
{
  get { return _visible; }
  set
  {
    _visible = value;
    ShowControl();
  }
}

But just replacing the Visible property is not enough. The two methods Show() and Hide() need to be replaced as well, to use our new Visible property.

public new void Show()
{
  this.Visible = true;
}
  
public new void Hide()
{
  this.Visible = false;
}

Add the TextBox

While we have already used our TextBox, we have not yet created it. We'll do that in the constructor.

public ReadOnlyComboBox()
{
  _textbox = new TextBox();
}

But that's not enough. We have to add the TextBox to the parent container and we have to copy several properties of the ComboBox to the TextBox. To add the TextBox, we override OnParentChanged() of the ComboBox.

protected override void OnParentChanged(EventArgs e)
{
  base.OnParentChanged(e);
   
  if (Parent != null)
    AddTextbox();
  _textbox.Parent = this.Parent;
}
   
private void AddTextbox()
{
  _textbox.ReadOnly = true;
  _textbox.Location = this.Location;
  _textbox.Size = this.Size;
  _textbox.Dock = this.Dock;
  _textbox.Anchor = this.Anchor;
  _textbox.Enabled = this.Enabled;
  _textbox.Visible = this.Visible;
  _textbox.RightToLeft = this.RightToLeft;
  _textbox.Font = this.Font;
  _textbox.Text = this.Text;
  _textbox.TabStop = this.TabStop;
  _textbox.TabIndex = this.TabIndex;
}

Rest

In the AddTextbox() method, we make sure that the TextBox has the same behavior (like size, location, docking, anchor, etc.) like the ComboBox. But what if one of these properties changes during runtime? We have to make sure that such changes are propagated from the ComboBox to the TextBox. Therefore, I override several of the OnXXXX() methods of the ComboBox. Just a few of the overridden methods as example:

protected override void OnSelectedIndexChanged(EventArgs e)
{
  base.OnSelectedIndexChanged(e);
  if (this.SelectedItem == null)
    _textbox.Clear();
  else
    _textbox.Text = this.SelectedItem.ToString();
}
  
protected override void OnEnabledChanged(EventArgs e)
{
  base.OnEnabledChanged(e);
  ShowControl();
}
  
protected override void OnDropDownStyleChanged(EventArgs e)
{
  base.OnDropDownStyleChanged(e);
  _textbox.Text = this.Text;
}
  
protected override void OnResize(EventArgs e)
{
  base.OnResize(e);
  _textbox.Size = this.Size;
}
  
protected override void OnLocationChanged(EventArgs e)
{
  base.OnLocationChanged(e);
  _textbox.Location = this.Location;
}

That's it. We finally have our ReadOnlyComboBox. In the same way, you could do a ReadOnlyDateTimePicker or a ReadOnlyNumericalUpDown and so on.

I will develop more read only enabled controls in the future. You'll find them here. Of course, if I have to implement one of them in a different way, I'll put it to CodeProject again.

History

  • 03/28/2005: Initial version.
  • 04/21/2005: First update.
    • Added: Show() and Hide() methods because the Show() and Hide() methods of the parent ComboBox did not use our new Visible property but the Visible property of the parent control.
    • Bugfix: OnSelectedIndexChanged raised an exception when no item was selected (thanks to Alexandre Cunha for reporting this bug).
    • Bugfix: The TextBox is now added in the OnParentChanged() method. That solves several problems compared to the old solution where it was added in the ReadOnly property (thanks again to Alexandre Cunha for reporting one of these problems).
    • Changed: When the ComboBox was disabled, it showed a disabled ComboBox as it should be. When it was disabled and at the same time ReadOnly was true, it showed a disabled TextBox. When disabled, it now always shows a disabled ComboBox.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Claudio Grazioli
Team Leader
Switzerland Switzerland
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pin
Hesham Eraqi17-Sep-13 5:47
memberHesham Eraqi17-Sep-13 5:47 
GeneralOne more problem solved - no more draging from Data Sources problems Pin
Tiago Freitas Leal19-Oct-09 14:19
memberTiago Freitas Leal19-Oct-09 14:19 
AnswerRead Only mode's "Enter" event missing Pin
jasonhammertime2-Apr-08 5:21
memberjasonhammertime2-Apr-08 5:21 
GeneralIncompatible with layout panels Pin
Chuck_Esterbrook27-Dec-06 13:44
memberChuck_Esterbrook27-Dec-06 13:44 
Generalprinting..... Pin
sam8sam21-Jun-06 21:49
membersam8sam21-Jun-06 21:49 
GeneralKeyDown event handler Pin
oskaremil24-May-06 4:19
memberoskaremil24-May-06 4:19 
GeneralRe: KeyDown event handler Pin
Claudio Grazioli24-May-06 7:38
memberClaudio Grazioli24-May-06 7:38 
GeneralRe: KeyDown event handler Pin
oskaremil24-May-06 11:41
memberoskaremil24-May-06 11:41 
General[Dispose] method must be overriden... Pin
KSM31-Mar-06 2:10
memberKSM31-Mar-06 2:10 
GeneralUnable to update on dropdownlist style Pin
John Choo1-Mar-06 3:02
memberJohn Choo1-Mar-06 3:02 
GeneralWhy not... Pin
AlexSoh21-Dec-05 6:43
memberAlexSoh21-Dec-05 6:43 
GeneralRe: Why not... Pin
Claudio Grazioli21-Dec-05 7:31
memberClaudio Grazioli21-Dec-05 7:31 
GeneralRe: Why not... Pin
AlexSoh21-Dec-05 7:48
memberAlexSoh21-Dec-05 7:48 
GeneralProblems with data binding Pin
Anonymous29-Sep-05 11:21
sussAnonymous29-Sep-05 11:21 
GeneralRe: Problems with data binding Pin
Claudio Grazioli30-Sep-05 6:53
memberClaudio Grazioli30-Sep-05 6:53 
GeneralRe: Problems with data binding Pin
Nima Dilmaghani30-Sep-05 15:16
sussNima Dilmaghani30-Sep-05 15:16 
GeneralSelectedItem does not work on OnSelectedIndexChanged Pin
Lalit Bhatia22-Sep-05 3:25
memberLalit Bhatia22-Sep-05 3:25 
GeneralRe: SelectedItem does not work on OnSelectedIndexChanged Pin
Ilíon25-Aug-06 18:52
memberIlíon25-Aug-06 18:52 
GeneralRe: SelectedItem does not work on OnSelectedIndexChanged Pin
csg120-Sep-06 12:23
membercsg120-Sep-06 12:23 
GeneralSame code for VB.NET Pin
ExplodingBoy19-Aug-05 8:09
sussExplodingBoy19-Aug-05 8:09 
Questionhow to create a property like this Pin
isgrom3-Jul-05 19:10
memberisgrom3-Jul-05 19:10 
AnswerRe: how to create a property like this Pin
Anonymous4-Jul-05 8:09
sussAnonymous4-Jul-05 8:09 
GeneralRead only combobox with dropdown list Pin
Patric_J19-May-05 9:53
memberPatric_J19-May-05 9:53 
GeneralRe: Read only combobox with dropdown list Pin
Claudio Grazioli19-May-05 21:37
memberClaudio Grazioli19-May-05 21:37 
GeneralI did it in a different way but not actually a readonly Pin
garapatiSridhar4-May-05 23:10
membergarapatiSridhar4-May-05 23:10 
GeneralI do the same thing using keypress event Pin
xknown26-Apr-05 19:43
memberxknown26-Apr-05 19:43 
GeneralRe: I do the same thing using keypress event Pin
Claudio Grazioli26-Apr-05 22:30
memberClaudio Grazioli26-Apr-05 22:30 
GeneralRe: I do the same thing using keypress event Pin
yoshi3215-Jan-07 7:27
memberyoshi3215-Jan-07 7:27 
GeneralUndesired behavior Pin
Alexandre Cunha19-Apr-05 14:41
sussAlexandre Cunha19-Apr-05 14:41 
GeneralRe: Undesired behavior Pin
Claudio Grazioli19-Apr-05 21:56
memberClaudio Grazioli19-Apr-05 21:56 
GeneralRe: Undesired behavior Pin
Claudio Grazioli19-Apr-05 22:09
memberClaudio Grazioli19-Apr-05 22:09 
GeneralRe: Can't reproduce - Workaround does not work Pin
Claudio Grazioli19-Apr-05 22:17
memberClaudio Grazioli19-Apr-05 22:17 
GeneralRe: Can't reproduce - Workaround does not work Pin
Alexandre Cunha20-Apr-05 7:39
sussAlexandre Cunha20-Apr-05 7:39 
GeneralRe: Can't reproduce - Workaround does not work Pin
Claudio Grazioli20-Apr-05 7:55
memberClaudio Grazioli20-Apr-05 7:55 
GeneralRe: Can't reproduce - Workaround does not work Pin
Alexandre Cunha20-Apr-05 8:04
sussAlexandre Cunha20-Apr-05 8:04 
GeneralBug Pin
Alexandre Cunha19-Apr-05 14:13
sussAlexandre Cunha19-Apr-05 14:13 
GeneralRe: Bug Pin
Claudio Grazioli19-Apr-05 21:54
memberClaudio Grazioli19-Apr-05 21:54 
GeneralSelectedIndex Pin
_Sady_14-Apr-05 1:49
suss_Sady_14-Apr-05 1:49 
GeneralRe: SelectedIndex Pin
Claudio Grazioli14-Apr-05 2:21
memberClaudio Grazioli14-Apr-05 2:21 
GeneralRe: SelectedIndex Pin
_Sady_14-Apr-05 2:26
suss_Sady_14-Apr-05 2:26 
GeneralRe: SelectedIndex Pin
_Sady_14-Apr-05 2:34
member_Sady_14-Apr-05 2:34 
GeneralDropDownStyle Pin
kps613-Apr-05 13:07
memberkps613-Apr-05 13:07 
GeneralRe: DropDownStyle Pin
Claudio Grazioli13-Apr-05 20:57
memberClaudio Grazioli13-Apr-05 20:57 
GeneralUsing OnParentChanged Pin
Sylvain Jérôme12-Apr-05 6:11
memberSylvain Jérôme12-Apr-05 6:11 
GeneralRe: Using OnParentChanged Pin
Claudio Grazioli12-Apr-05 7:59
memberClaudio Grazioli12-Apr-05 7:59 
GeneralOther Values Pin
swylie5-Apr-05 12:21
memberswylie5-Apr-05 12:21 
GeneralRe: Other Values Pin
Claudio Grazioli5-Apr-05 22:26
memberClaudio Grazioli5-Apr-05 22:26 
GeneralRe: Other Values Pin
eshipman13-Apr-05 12:03
membereshipman13-Apr-05 12:03 
GeneralI like the idea but... Pin
Robert Rohde27-Mar-05 22:45
memberRobert Rohde27-Mar-05 22:45 
GeneralRe: I like the idea but... Pin
Claudio Grazioli27-Mar-05 22:59
memberClaudio Grazioli27-Mar-05 22:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150520.1 | Last Updated 26 Apr 2005
Article Copyright 2005 by Claudio Grazioli
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid