.NET Winforms Combobox databinding with ComboBoxStyle.DropDownList

Neil Hamilton Jr 1 Reputation point
2021-01-12T02:58:06.627+00:00

I'm running into a weird issue with databinding the Text property of a combobox to a string property of a custom object. I was able to successfully bind the data when the DropDownStyle was ComboBoxStyle.DropDown. However, I need a read only combobox so I needed to change the style to DropDownList. When I did this, the Text property no longer updates the custom object. (The setter for the property is never executed). I've checked the BindingComplete event args to see if there were any binding errors and the binding was successful.

I've also tried to bind to SelectedValue, SelectedItem and neither work.

Looking at the documentation 'Text' is listed as a BindableAttribute and the description of the DropDownList style mentions nothing of disabling data binding.

// This class has a 'StringValue' property for the current string representation of the value of the parameter
// It also has a method 'DisplayNames' which returns a list of the valid string values this parameter can have
// The class has implemented INotifyPropertyChanged
Parameter p = new Parameter();

ComboBox cobx = new ComboBox();
cobx.Name = p.Name + "_ComboBox";
cobx.Items.AddRange(ep.DisplayNames().ToArray());
cobx.Text = p.StringValue;
cobx.AutoSize = true;
cobx.DropDownStyle = ComboBoxStyle.DropDownList;

Binding b = new Binding("Text", ep, "StringValue", true, DataSourceUpdateMode.OnPropertyChanged);
b.BindingComplete += new BindingCompleteEventHandler(control_BindingComplete);
cobx.DataBindings.Add(b);

//cobx.DataBindings.Add("Text", ep, "StringValue", false, DataSourceUpdateMode.OnPropertyChanged);

void control_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteState != BindingCompleteState.Success)
int break_pt_here = 0;
}

I'm running Windows 10
Project is being compiled against .NET 4.7.2
I'm using WinForms

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,862 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,458 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Daniel Zhang-MSFT 9,621 Reputation points
    2021-01-12T06:30:46.443+00:00

    Hi NeilHamiltonJr-4091,
    When using the DropDownList style, you can only set "Text" to the value that actually appears in the list.
    Here is my test code example:

    private void Form1_Load(object sender, EventArgs e)  
    {    
        MyData data = new MyData() { Name = "Red" };  
        this.bindingSource1.DataSource = data;  
        comboBox1.DataBindings.Add(new Binding("SelectedValue", this.bindingSource1, "MyEnum", true, DataSourceUpdateMode.OnPropertyChanged));  
        comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;  
        comboBox1.FormattingEnabled = true;  
      
        comboBox1.Items.AddRange(new object[] { "", "Green", "Red", "Yellow", "Blue", "Gold", "Purple" });  
        comboBox1.Text = data.Name;  
        comboBox1.Location = new System.Drawing.Point(98, 87);  
        comboBox1.Name = "shiftColourComboBox";  
        comboBox1.Size = new System.Drawing.Size(121, 21);  
    }  
    

    The result:
    55623-112111.png
    Best Regards,
    Daniel Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Neil Hamilton Jr 1 Reputation point
    2021-01-12T22:18:17.493+00:00

    I eventually got it to work. My guess is that when the DropDownList style is selected the combo box drifts to more of the ListControl. Looking at that class I saw the DataSource, DisplayMember, ValueMember. I ended up changing the DisplayNames() method to return a List<EnumString>

    class EnumString{ public string Value {get; set;}}

    I passed that List to the DataSource with DisplayMember as 'Value' and ValueMember as 'Value'. SelectedValue was then populated on selection of a combobox item.

    Then using this binding
    cobx.Databindings.Add("SelectedValue", p, "StringValue", true, DataSourceUpdateMode.OnPropertyChanged);

    Seems to be working. I feel like there is a better way. I'll have to refactor some classes with some of this in mind.

    Anyway, thank you, Daniel.

    0 comments No comments