Introduction
Given that there is no ReadOnly
property for the WinForm Controls: ComboxBox
, DateTimePicker
and CheckedListBox
, this tip describes an implementation to set these controls as read-only.
Background
When implementing a single WinForm for both data view and input purpose, I found it useful if I could set these types of controls as read-only just like using the ReadOnly
property of some controls (e.g. TextBox
).
Using the Code
The following is the code snippet of the extension methods to customize the controls with read-only properties and behaviours.
static class ControlsExtension
{
public static void SetReadOnly(this ComboBox cmb, bool readOnly)
{
cmb.KeyDown -= new KeyEventHandler(SuppressKeyPressHandler);
if (readOnly) cmb.KeyDown += new KeyEventHandler(SuppressKeyPressHandler);
cmb.DropDownStyle = (readOnly) ? ComboBoxStyle.Simple : ComboBoxStyle.DropDown;
cmb.BackColor = (readOnly) ? SystemColors.Control : SystemColors.Window;
}
public static void SetReadOnly(this DateTimePicker dtp, bool readOnly)
{
string textBoxName = string.Format("txt{0}", dtp.Name);
TextBox textBox = dtp.Parent.Controls[textBoxName] as TextBox;
if (readOnly)
{
if (textBox == null)
{
textBox = new TextBox()
{
Name = textBoxName,
ReadOnly = true,
BackColor = SystemColors.Control,
Size = dtp.Size,
Location = dtp.Location,
TabIndex = dtp.TabIndex
};
dtp.Parent.Controls.Add(textBox);
}
textBox.Text = dtp.Text;
}
dtp.Visible = !readOnly;
if (textBox != null) textBox.Visible = readOnly;
}
public static void SetReadOnly(this CheckedListBox clb, bool readOnly)
{
clb.KeyDown -= new KeyEventHandler(SuppressKeyPressHandler);
if (readOnly) clb.KeyDown += new KeyEventHandler(SuppressKeyPressHandler);
clb.ItemCheck -= new ItemCheckEventHandler(SuppresItemCheckHandler);
if (readOnly) clb.ItemCheck += new ItemCheckEventHandler(SuppresItemCheckHandler);
clb.BackColor = (readOnly) ? SystemColors.Control : SystemColors.Window;
}
static void SuppressKeyPressHandler(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
static void SuppresItemCheckHandler(object sender, ItemCheckEventArgs e)
{
e.NewValue = e.CurrentValue;
}
}
So, to apply them like:
comboBox1.SetReadOnly(true);
dateTimePicker2.SetReadOnly(true);
checkedListBox3.SetReadOnly(true);
And the sample results are illustrated as below:
The approach to set controls as read-only is simply nothing more than suppressing user interaction with the controls. But for DateTimePicker
, it shows a read-only TextBox
instead since I could not find a way to get rid of its drop-down calendar button.
Points of Interest
ComboxBox
, DateTimePicker
and CheckedListBox
have Enabled
properties that can be set to false
for similar effect:
However:
- the text is dimmed.
- the drop down button is still shown for
ComboBox
and DateTimePicker
.
- the back colour is not changed for
CheckedListBox
.
History
- 14th October, 2015 - First publication