C# combobox selected index changed fires old value

I have a situation when I want to change the selected value of a combo box in a windows forms application by using Ctrl-Left ori Ctrl-Right. However if the combobox is the selected control on the form this does not work. The selected value is set to the old value after it is set to the new value. If the combobox is not the selected control then everything works fine. In my application the combo can receive focus because the values can also be changed with the mouse. While what I want can be accomplished by selecting some other control on the form before actually changing the value I don't like this solution to much.

So, there are two questions: Why is the selectedIndexChanged event fired with the old value if the combo box is the selected control on the form and How can avoid this or if I can't what is a good workaround ? Further is some code to illustrate my issue. If you drop a combo box and a richtext box on a form and copy the below code in Form1.cs you can see my problem. You need to make the combo DropDownList Style and add some numbers as items (1, 2, 3 is fine)

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        comboBox1.SelectedIndex = 0;
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Control | Keys.Left))
        {
            DoUpdate();
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

    private void DoUpdate()
    {
        int index = Convert.ToInt32(comboBox1.SelectedItem);
        index++;
        if (comboBox1.Focused)
            richTextBox1.Select();
        comboBox1.SelectedItem = index.ToString();
    }

    private void SetComboValue(int value)
    {
        comboBox1.SelectedItem = value.ToString();
        richTextBox1.AppendText(string.Format("Set value {0} rn", value.ToString()));         
    }

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        richTextBox1.AppendText(string.Format("Selected index changed before {0}rn", comboBox1.SelectedItem));
        SetComboValue(Convert.ToInt32(comboBox1.SelectedItem));
        richTextBox1.AppendText(string.Format("Selected index changed after {0}rn", comboBox1.SelectedItem));
    }
}

This is caused by the fact that by default, if the combobox has focus, then pressing left and right(without control) will change the value.

You are catching ctrl-left, incrementing the value ... and then passing on the keypress to the base object, which interprets the left keypress and decrements the selected item.

Change your code as follows, to swallow the keypress, and things seem to work as expected:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Control | Keys.Left))
        {
            DoUpdate();
            return true;
        }
        else
        {
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }

Why don't you just run the SetComboValue method from your DoUpdate method? If that doesn't work you could always set a flag that states it's set from the DoUpdate method and only run the selected index changed event when directly accessed. Just a thought.

We do something similar when we have a bunch of events tied to comboboxes and lists during our load of the form. We are setting values and don't want the events to fire during load so we have a flag that keeps the events from firing until the form load is complete.

My thought is that you are setting the value but something else is forcing a second selecteditem change event to occur. However it also looks like you could get into a endless loop since you set the selectedindex in the DoUpdate method and the SetComboValue method.

Just change the selected index in one place.

链接地址: http://www.djcxy.com/p/68590.html

上一篇: 在网络中处理Windows应用程序中的组合框事件(c#)

下一篇: C#combobox选择的索引更改了旧的值