.NET WinForms ComboBox, identical elements and SelectedIndexChanged event

It looks like when you have the WinForms.NET and ComboBox applications (installed in the DropDown style), and that the ComboBox has several elements in it that are identical, strange things happen. In particular, the index of the selected item may change without triggering the SelectedIndexChanged event.

Of course, this causes massive confusion and strange, unclear errors, due to which I recently pulled my hair.

Here is a simple example that you can use to find out what I'm talking about:

  • Create a new .NET WinForms project (I use VB.NET, but feel free to translate - it's easy enough).
  • Drop the ComboBox, button and TextBox (set MultiLine = True) to the form.
  • Use the following code to load a ComboBox with three identical elements, and to print some status messages when the SelectedIndexChanged event occurs, and to view the currently selected index (using the button):
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        TextBox1.Text = TextBox1.Text & vbNewLine & "ComboBox SelectedIndexChanged event fired." & vbNewLine & _
            "SelectedIndex is: " & ComboBox1.SelectedIndex
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ComboBox1.Items.Add("John Doe")
        ComboBox1.Items.Add("John Doe")
        ComboBox1.Items.Add("John Doe")

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TextBox1.Text = TextBox1.Text & vbNewLine & _
        "Button clicked." & vbNewLine & _
        "SelectedIndex is: " & ComboBox1.SelectedIndex
    End Sub

Run the project and select an item from ComboBox (say, middle). Then click the combobox drop-down arrow, but DO NOT CHOOSE ANYTHING. Click the button (Button1 by default) and see what it says.

If I havenโ€™t lost my mind, here is what you should see:

ComboBox SelectedIndexChanged event fired.
SelectedIndex is: 1
Button clicked.
SelectedIndex is: 0

In other words, the SELECTED INDEX is CHANGED, but without triggering the SelectedIndexChanged event!

, ComboBox . , . ( , ComboBox "DropDown" "DropDownList".)

, โ€‹โ€‹ .NET, -, , , - , ( !), , ! ( , SelectedIndex , , , , - !)

+5
4

.NET Framework ; Windows API. .NET API Windows, , , , SelectedIndexChanged.

, , , .NET(CBN_SELCHANGE, ), , . , CBN_SELCHANGE Windows API, . DropDown Windows , , , ( , ). , CBN_SELCHANGE, .NET , SelectedIndexChanged.

Windows DropDown, - ; , . , , , , , .

, , , "John Doe" # 0, 0, .NET.

.NET Framework. , - Windows , , , . ( DropDown , .) , , DropDownClosed, , .

+17

, , , "... , , ". .Net, , , , , , , .

? ? ? , , . , .

, , , - , , , .

, , , , , . , , , , , , , , .

+1

, , . OpenFileDialog, Visual Studio, " ". , " ", " ", " " .. . . , () .

:

C:\
C:\A
C:\A\B
C:\A\B\A

. DataSource BindingList . ValueMember - , DisplayMember - . :

C:\
    A
        B
            A

. .

SelectedValue "C:\A\B\A", . , , (4- ) , ( 1). SelectedIndex = 3 , . , , .

, , SelectedValue SelectedIndex DisplayMember, . ValueMember. . , - , , -, .

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ComboBoxTest
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private void Form1_Load(object sender, EventArgs e)
      {
         if (DesignMode)
            return;

         BindingList<CBItem> items = new BindingList<CBItem>();
         items.Add(new CBItem("A", @"C:\A"));
         items.Add(new CBItem("B", @"C:\A\B"));
         items.Add(new CBItem("A", @"C:\A\B\A"));

         comboBox.DisplayMember = "DisplayValue";
         comboBox.ValueMember = "RealValue";
         comboBox.DataSource = items;

         comboBox.SelectedValue = @"C:\A\B\A";
      }
   }

   class CBItem
   {
      public CBItem(string displayValue, string realValue)
      {
         _displayValue = displayValue;
         _realValue = realValue;
      }

      private readonly string _displayValue, _realValue;

      public string DisplayValue { get { return _displayValue; } }
      public string RealValue { get { return _realValue; } }
   }
}
+1

, , , . , , -1, . ( - , ) . , , combobox , , . , . , .

0

All Articles