Search code examples
c#winformscomboboxvaluemember

Multiple ValueMembers From One ComboBox C#


I would like to assign more than 1 field to value member in a combobox. As can be seen from the code, the current string assigned to value member is "title", and in the cboCustomers_SelectionChangeCommited event, you can see a textbox has been assigned the selected value.

What I hope to achieve is to have 2 further fields assigned to value member ("firstname", "lastname") and have two further textboxes assigned with these values.

I hope I have been clear. If not, please specify and I will attempt to re-explain.

 private void Form3_Load(object sender, EventArgs e)
                    {
                        try
                        {
                            dbConn = new OleDbConnection(conString);
                            sql = @"SELECT customer.title, firstname, lastname, product.name, account.balance
                                  FROM (account INNER JOIN customer ON account.custid = customer.custid) INNER JOIN product ON account.prodid = product.prodid;";

                            daItems = new OleDbDataAdapter(sql, dbConn);
                            daItems.Fill(dtAccBal);


                            cboCustomers.DataSource = (dtAccBal);
                            cboCustomers.DisplayMember = "firstname";
                            cboCustomers.ValueMember = "title";
                            cboCustomers.SelectedIndex = -1;

                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Error!");
                        }
                    }


                    private void cboCustomers_SelectionChangeCommitted(object sender, EventArgs e)
                    {
                        if (cboCustomers.SelectedIndex > -1)
                        {
                            try
                            {
                                txtTitle.Text = cboCustomers.SelectedValue.ToString();



                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Error!");
                            }
                        }
                    }
                }

Solution

  • You can use object that implements INotifyPropertyChanged interface and add DataBindings to your TextBoxes.

    Example:

    Class Person that implements INotifyPropertyChanged

    public class Person : INotifyPropertyChanged
    {
        private string _firstName;
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (value == _firstName) return;
                _firstName = value;
                OnPropertyChanged();
            }
        }
    
        private string _lastName;
        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (value == _lastName) return;
                _lastName = value;
                OnPropertyChanged();
            }
        }
    
        public override string ToString() => $"{FirstName} {LastName}";
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Add on form ComboBox "comboBoxPeople" and two TextBoxes "textBoxFirstName", "textBoxLastName".

    Change constructor of form:

    public Form1()
    {
        InitializeComponent();
    
        var people = new BindingList<Person> {
            new Person() { FirstName = "Peter", LastName = "Pan" },
            new Person() { FirstName = "Tinker", LastName = "Bell" },
            new Person() { FirstName = "James", LastName = "Hook" },
            new Person() { FirstName = "Wendy", LastName = "Darling" },
        };
    
        var bindingSource = new BindingSource() { DataSource = people };
    
        comboBoxPeople.DataSource = bindingSource;
        textBoxFirstName.DataBindings.Add(nameof(TextBox.Text), bindingSource, nameof(Person.FirstName), false, DataSourceUpdateMode.OnPropertyChanged);
        textBoxLastName.DataBindings.Add(nameof(TextBox.Text), bindingSource, nameof(Person.LastName), false, DataSourceUpdateMode.OnPropertyChanged);
    }
    

    Now you have a combo box filled with people. After select another person text boxes will be populated with appropriate data automatically.