Introduction
Just like a lot of people, I was looking for a read-only combobox. Most of the code samples available are complex, have some faults or just aren't that kind of read-only we want. So I went looking for a simple solution using Windows messages to keep the drop-down closed. As you will see in this article, the code is pretty easy.
Using the code
Inherit a class from a combobox and override the events that can modify the value of it. Under events, you can check if the combobox is read-only, as well as block or ignore the input.
class RoComboBox : System.Windows.Forms.ComboBox
{
private bool readOnly;
public bool ReadOnly
{
get { return readOnly;}
set { readOnly = value;}
}
protected override void
OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
if (readOnly)
e.Handled = true;
base.OnKeyDown(e);
}
protected override void
OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
if (readOnly)
e.Handled = true;
base.OnKeyPress(e);
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if ((m.Msg != 0x201 && m.Msg != 0x203) || !readOnly)
base.WndProc(ref m);
}
}
So, what is this code doing?
It is adding a private field and a property called ReadOnly.
private bool readOnly;
public bool ReadOnly
{
get { return readOnly;}
set { readOnly = value;}
}
Override
KeyDown and
KeyPress; check if the property
ReadOnly is true and set as
Handled. Then
KeyPress will not modify the combobox value.
protected override void
OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
if (readOnly)
e.Handled = true;
base.OnKeyDown(e);
}
protected override void
OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
if (readOnly)
e.Handled = true;
base.OnKeyPress(e);
}
The last thing you have to do is block the mouse to prevent the drop-down from opening. You can do this by overriding the
WndProc of the combobox and checking the type of Windows message. Block the mouse buttons when the property
ReadOnly is set.
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if ((m.Msg != 0x201 && m.Msg != 0x203) || !readOnly)
base.WndProc(ref m);
}
Points of interest
If you want to know more about Windows messages or look for some constant values for them, check out
http://www.pinvoke.net/default.aspx/Constants.WM
History
Original version posted: May 7, 2007
After my studies i started as a technician for repair of consumer electronics at the philips company in Brussels, more specific laser, camcorder and PC products. This was not really software related but it gave me good knowledge about global architectures and bus systems.
In 1998 i started as delphi developer for 9 years, mainly for developing realtime auction software. So i’ve done a lot of programming for serial,network and internet communication, audiostreaming included. In the same period i’ve developed databases for those multitier applications on a MSSQL server.
August 2006 i’ve switched to the C# .net environment, writing applications for a company providing access control solutions. Though the developing was mainly for enduser software, i also had to write automatisation software.