1

Is this truly a bug in Winforms in 2015 or am I just doing something wrong...

1) Create a new winforms project (.net 4.0) and add a combobox to the main form. 2) Use this for your form load code:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Dim items As New Dictionary(Of Integer, String)

    items.Add(1, "Value 1")
    items.Add(2, "Value 2")
    items.Add(3, "Value 3")
    items.Add(4, "Value 3")

    Dim dataSource As New BindingSource(items, Nothing)
    ComboBox1.DataSource = dataSource

    ComboBox1.DisplayMember = "Value"
    ComboBox1.ValueMember = "Key"

End Sub

Notice how items 3 & 4 have the same value, but different keys and that the display and value members are set correctly (unless I am going crazy, which is possible). When you run the application, open the combobox and select the last item. Now, open the combobox back up and you will notice that the 2nd to last item is now selected. That is a problem.

Any thoughts?

Thanks!

EDIT: I added an Infragistics UltraComboEditor to the form and placed the following code in the form load event:

    For Each item As KeyValuePair(Of Integer, String) In items
        UltraComboEditor1.Items.Add(New ValueListItem With {.DataValue = item.Key, .DisplayText = item.Value})
    Next

    UltraComboEditor1.SelectedIndex = 0
    UltraComboEditor1.AutoComplete = True

The Infragistics control allows me to autocomplete and enter my own text and it is not changing my selection when I select an item with the same text as the item above it. The Winforms control should not be changing my selection like that.

DonnieDarko
  • 93
  • 1
  • 14
  • Change your dropdown style to `DropDownList`. The user can type partial text into one which is `DropDown` style and the CBO will search for the first text matching what is entered in the text portion. You apparently do not like this. – Ňɏssa Pøngjǣrdenlarp Apr 22 '15 at 20:56
  • The user needs to be able to enter their own value, is that supported with DropDownList? – DonnieDarko Apr 22 '15 at 21:01
  • It's not that I don't like it, it is that I explicitly select the 4th item and somehow the control goes and switches it back to the 3rd item. I need all of that functionality and I need for the user to be able to start typing and have it select the first one. This issue has nothing to do with the user typing anything. – DonnieDarko Apr 22 '15 at 21:02
  • Why do you have two items with the same Value but different Key? Is not this a situation that need to be addressed? How can your user differentiate between the two values? I am asking this because I wish to understand if it is possible to choose a different approach – Steve Apr 22 '15 at 21:11
  • Steve - We have a customers table. Some customers are identified by their contact name, so the business name is the same (shows in the drop down) but the customer contact behind the name and the ID is different. I know, not ideal but that is the situation I am in. It really shouldn't matter though, the control should be using the ValueMember of the item, not the text. – DonnieDarko Apr 22 '15 at 21:16
  • I agree with you but... [You could read this answer](http://stackoverflow.com/questions/354408/net-winforms-combobox-identical-items-and-the-selectedindexchanged-event?rq=1) for a detailed explanation. I would change the way in which you populate the ComboBox adding some other text to the name of the contact (like the company) Something like `items.Add(Company.ID, Company.ContactName & " (" & Company.Name & ")")` – Steve Apr 22 '15 at 21:29
  • This 'issue' is well known and is not a bug. Under no circumstances should you have two values in a combobox with the same text. If there are 5 John Does to choose from, how do I know that the 3rd one in the list is the John Doe from XYZ company that I want to select? You need to include more information. If you really don't want to include extra info such as the company name next to the contact name (or if you want to avoid the situation of having 2 John Does at the same company) you could even prepend a number onto the text so you have `1) John Doe` `2) John Doe` `3) Bob Smith` etc. – Joe Uhren Apr 22 '15 at 21:42
  • @JoeyJoeJoeJrShabadoo I consider it a bug. When we had only the Item text then the behavior is justifiable but when you set a `ValueMember` and allow to add complex data object then... I can only suppose that probably the Windows Dev Team doesn't hear the screams from the NET Dev Team – Steve Apr 22 '15 at 22:35
  • 1
    @Joey, I disagree. "Under no circumstances should you have two values in a combobox with the same text." That is an opinion. I would tend to agree with it as well, but I am only working with what I have. Other information is displayed to the user upon selection so that they know which item is selected. Not the best, but it is what I am working with. The fact that there is a "ValueMember" property which is not being respected tells me that yes, it is a bug. FYI, the Infragistics controls handle this situation just fine. Bug. – DonnieDarko Apr 22 '15 at 22:42
  • Try this: http://stackoverflow.com/questions/28581471/same-two-items-in-combobox-but-first-one-always-gets-selected-c-sharp – Barbarossa Mar 20 '17 at 13:46

1 Answers1

1

When the ComboBox allows the text portion to be edited, then it will pattern match and highlight the first prefix text that matches. This has the side effect that when the listbox is closed, the selected item is updated.

When the ComboBox's DropDownStyle == DropDownList mode, then the item previously selected will be highlighted in the dropdown list.

You can change the behavior by assigning a NativeWindow to the list window and then listen for the LB_SETCURSEL Msg.

You can use this thread as a starting point: Prevent AutoSelect behavior of a System.Window.Forms.ComboBox (C#)

Add an int index field to the Data object. Then in the Register method add:

    combo.SelectedIndexChanged += delegate {
        data.index = combo.SelectedIndex;
    };

Then pass the Data to the native window, which keeps track of the previously selected index.

private class NW : NativeWindow {
    Data data;
    public NW(IntPtr handle, Data data) {
        this.AssignHandle(handle);
        this.data = data;
    }

    private const int LB_FINDSTRING = 0x018F;
    private const int LB_FINDSTRINGEXACT = 0x01A2;
    private const int LB_SETCURSEL = 0x0186;

    protected override void WndProc(ref Message m) {
        if (m.Msg == LB_FINDSTRING)
            m.Msg = LB_FINDSTRINGEXACT;

        if (m.Msg == LB_SETCURSEL)
            m.WParam = (IntPtr) data.index;

        base.WndProc(ref m);
    }
}
Community
  • 1
  • 1
Loathing
  • 5,109
  • 3
  • 24
  • 35
  • Thank you very much, this would do the trick if I didn't need auto-complete. I really don't understand why it is trying to auto-complete when the user has actually selected an item in the list with their mouse and have not typed anything. That's why I would consider this a bug, it shouldn't be doing that (like Infragistics). I do need the auto-complete behavior so I am just going to switch to the Infrgistics or DevExpress control that handles this situation without this little issue. I was just curious if I was perhaps data binding incorrectly or setting a property wrong or something. – DonnieDarko Apr 23 '15 at 15:03
  • You can take out the `m.Msg == LB_FINDSTRING` if statement, which will probably make autocomplete work again. That was really just there for the solution on the other thread. – Loathing Apr 23 '15 at 15:42
  • Sorry it's been ages since I've been able to get back to this. Hoping to try it soon... Thanks again! – DonnieDarko Oct 25 '17 at 20:47