Reinderien
Reinderien

Reputation: 15221

Read-only (but droppable) ComboBox

I'm looking to build a Windows Forms combo box that has normal coloration, and allows the dropdown list to appear, but does not allow the value to actually change. As far as I can tell, this is not a duplicate of How to make Combobox in winforms readonly since all advice there seems to be directed toward disabling the combo box's interactivity.

My rationale: I have a form where all of the controls are read-only, and due to the nature of the application I think that there would be no risk of the user getting confused when the combo box's value does not change. I would like the user to be able to see all of the possible values of the enum to which the combo box is bound.

What I have so far is a pretty bad hack:

public partial class ReadOnlyComboBox : ComboBox
{
    int prevIndex = -1;

    public ReadOnlyComboBox()
    {
        InitializeComponent();
    }

    private void ReadOnlyComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (prevIndex <= 0)
            prevIndex = SelectedIndex;
        else
            SelectedIndex = prevIndex;
    }
}

In effect, this ignores spurious "0" values from the framework, and takes the first non-zero value acquired from a binding source. Immediate disadvantages are that the value may only be set once, and that the bound enum must start at 1.

Any advice on cleaning this up would be welcome. Thanks.

Upvotes: 3

Views: 942

Answers (1)

Avram
Avram

Reputation: 4259

Use DropDownClosed event

public class ReadOnlyComboBox : ComboBox
{
    bool afterDropDown ;
    int prevIndex;

    public ReadOnlyComboBox()
    {
        this.SelectedIndexChanged+=new EventHandler(ReadOnlyComboBox_SelectedIndexChanged);
        this.DropDownClosed += new EventHandler(ReadOnlyComboBox_DropDownClosed);
    }

    void ReadOnlyComboBox_DropDownClosed(object sender, EventArgs e)
    {
        afterDropDown = true;
    }

    private void ReadOnlyComboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (afterDropDown)
        {
            afterDropDown = false;
            SelectedIndex = prevIndex;
        }
        else
        {
            prevIndex = SelectedIndex;
        }
    }
}

Upvotes: 1

Related Questions