Setting SelectedIndex in ComboBox DropDown eventhandler

I recently reproduced the strange behavior of this message on my Windows 7. Maybe this is a feature, and maybe it does not depend on Windows 7, please correct me if this is the correct behavior. In MSDN we see

The application sends a CB_SETCURSEL message to select a row in the combo box list. If necessary, the list scrolls the line in sight. The text in the edit control of the combo box changes to reflect the new selection, and any previous selection in the list is deleted.

The following is a code snippet describing the hot function for playback:

private void ReproduceBehaviour()
{
    ComboBox comboBox = new ComboBox();
    Controls.Add(comboBox);
    comboBox.DataSource = new List<string> { "A", "b", "B", "C" };
    comboBox.DropDown += new EventHandler((o, e) => { comboBox.SelectedIndex = 2; });
}

So, when we set SelectedIndex = 2 in the drop-down list, select "B". But it is strange to me that the item "b" is selected (with index = 1)! We can send CB_SETCURCELL message directly, nothing has changed:

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
private void ReproduceBehaviour()
{
    ComboBox comboBox = new ComboBox();
    Controls.Add(comboBox);
    comboBox.DataSource = new List<string> { "A", "b", "B", "C" };
    comboBox.DropDown += new EventHandler((o, e) => { SendMessage(comboBox.Handle, 0x14e, 2, 0); });
}

Is this function (?! O_O) or what am I doing wrong? Thanks for answers.

UPD As recommended, I tried to manually set the selection to the list in the dropdown event handler. No effect: (

private void ReproduceBehaviour()
{

    ComboBox comboBox = new ComboBox();
    Controls.Add(comboBox);
    comboBox.DataSource = new List<string> { "A", "b", "B", "C" };
    comboBox.DropDown += new EventHandler((o, e) =>
    {
        SendMessage(comboBox.Handle, 0x14e, 2, 0); // CB_SETCURSEL
        ComboBoxInfo pcbi = new ComboBoxInfo();
        pcbi.cbSize = Marshal.SizeOf(pcbi);
        GetComboBoxInfo(comboBox.Handle, ref pcbi);
        IntPtr result = SendMessage(pcbi.hwndList, 0x0186, 2, 0); // LB_SETCURSEL
    });
}

I need to use LB_SETCURSEL because LB_SETSEL returned LB_ERR (LB_SELSET is only available for multi-second lists, but ComboBox uses a singleleeslectional listbox). Method call

IntPtr result = SendMessage(pcbi.hwndList, 0x0186, 2, 0); // LB_SETCURSEL

'2', , . , , :( , DropDown ? .

+3
1

, . SelectedIndex, , . , , . , .

, , , "D". . "b", .

, . CB_GETCOMBOBOXINFO, LB_SETSEL. , . , .

+2

Source: https://habr.com/ru/post/1752671/


All Articles