65.9K
CodeProject is changing. Read more.
Home

Set ComboBox/DateTimePicker/CheckedListBox Read-only

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2 votes)

Oct 14, 2015

CPOL
viewsIcon

10341

Make these controls read-only on WinForm

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
    {
        // Extension method for ComboBox
        public static void SetReadOnly(this ComboBox cmb, bool readOnly)
        {
            // If readonly, attach handler to suppress any key press
            cmb.KeyDown -= new KeyEventHandler(SuppressKeyPressHandler);
            if (readOnly) cmb.KeyDown += new KeyEventHandler(SuppressKeyPressHandler);

            // Control drop down display
            cmb.DropDownStyle = (readOnly) ? ComboBoxStyle.Simple : ComboBoxStyle.DropDown;

            // Set back colour
            cmb.BackColor = (readOnly) ? SystemColors.Control : SystemColors.Window;
        }

        // Extension method for DateTimePicker
        public static void SetReadOnly(this DateTimePicker dtp, bool readOnly)
        {
            // Get read-only TextBox
            string textBoxName = string.Format("txt{0}", dtp.Name);
            TextBox textBox = dtp.Parent.Controls[textBoxName] as TextBox;
            if (readOnly)
            {
                if (textBox == null)
                {
                    // Create read-only TextBox
                    textBox = new TextBox()
                    {
                        Name = textBoxName,
                        ReadOnly = true,
                        BackColor = SystemColors.Control,
                        Size = dtp.Size,
                        Location = dtp.Location,
                        TabIndex = dtp.TabIndex
                    };
                    dtp.Parent.Controls.Add(textBox);
                }

                // Show DateTimePicker value in read-only TextBox
                textBox.Text = dtp.Text;
            }

            // Decide which control to show based on readOnly
            dtp.Visible = !readOnly;
            if (textBox != null) textBox.Visible = readOnly;
        }

        // Extension method for CheckedListBox
        public static void SetReadOnly(this CheckedListBox clb, bool readOnly)
        {
            // If readonly, attach handler to suppress any key press
            clb.KeyDown -= new KeyEventHandler(SuppressKeyPressHandler);
            if (readOnly) clb.KeyDown += new KeyEventHandler(SuppressKeyPressHandler);

            // If readonly, attach handler to suppress any item check
            clb.ItemCheck -= new ItemCheckEventHandler(SuppresItemCheckHandler);
            if (readOnly) clb.ItemCheck += new ItemCheckEventHandler(SuppresItemCheckHandler);

            // Set back colour
            clb.BackColor = (readOnly) ? SystemColors.Control : SystemColors.Window;
        }

        // Handler to suppress key press
        static void SuppressKeyPressHandler(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
        }

        // Handler to suppress item check
        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:

  1. the text is dimmed.
  2. the drop down button is still shown for ComboBox and DateTimePicker.
  3. the back colour is not changed for CheckedListBox.

History

  • 14th October, 2015 - First publication