1

Code

I have this UI

Screenshot of UI

with this code

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;

namespace WinFormsComboBoxDatabinding
{
    public partial class Form1 : Form
    {
        public List<Person> PersonList { get; set; }
        public Person SelectedPerson { get; set; }

        public Form1()
        {
            InitializeComponent();
            InitializePersonList();
            InitializeDataBinding();
        }

        private void InitializePersonList()
        {
            PersonList = new List<Person>
            {
                new Person { FirstName = "Bob", LastName = "Builder" },
                new Person { FirstName = "Mary", LastName = "Poppins" }
            };
        }

        private void InitializeDataBinding()
        {
            SelectedPerson = PersonList[0];

            var bindingSource = new BindingSource();
            bindingSource.DataSource = PersonList;

            comboBox.DisplayMember = "FirstName";
            //comboBox.ValueMember = "LastName";
            comboBox.DataSource = bindingSource;

            textBoxFirstName.DataBindings.Add("Text", SelectedPerson, "FirstName");
            textBoxLastName.DataBindings.Add("Text", SelectedPerson, "LastName");
        }

        private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            SelectedPerson = comboBox.SelectedItem as Person;

            Debug.WriteLine($"SelectedPerson: {SelectedPerson}");
        }
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public override string ToString()
        {
            return $"{FirstName} {LastName}";
        }
    }
}

Questions

I have two questions about databinding:

  1. When I select Mary in the ComboBox, the two TextBox controls don't get updated. Why is that? What did I do wrong?

    Screenshot of UI

    Screenshot of Debug output

  2. When I change the text "Mary" in the ComboBox, the SelectedPerson object doesn't get updated with the new FirstName, say "Mary changed", from the ComboBox. How would I achieve that behaviour of changing the ComboBox FirstName to update the FirstName of the SelectedPerson? Or is that not possible with a ComboBox?

    UI of Mary changed

    Debug output of Mary changed

Other experiment

  • I've seen that one can set the two TextBox controls' Text property when comboBox_SelectedIndexChanged gets called, but that's not really databinding, is it. That would be manually doing all the updating logic.

Let me know if I need to add more details to the question.

Lernkurve
  • 20,203
  • 28
  • 86
  • 118

3 Answers3

0

You don't need the SelectedPerson variable. It looks like you just have the wrong DataSource wired up. Try it this way:

textBoxFirstName.DataBindings.Add("Text", bindingSource, "FirstName");
textBoxLastName.DataBindings.Add("Text", bindingSource, "LastName");
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • Indeed, that solved the problem from question 1 and updating the FirstName in the Textbox updates the ComboBox. Thank you! Any insights on question 2? – Lernkurve Jan 08 '19 at 21:43
  • 1
    @Lernkurve If you change the value of the name from the TextBox, it works (when the TextBox loses focus, it updates the property). Doing it from the ComboBox is a bit of a weird place to do that. – LarsTech Jan 08 '19 at 21:50
0

You just need to set the ComboBox.DataSource to the List<Person> object, represented by the PersonList property here.
Add a DataBinding to the controls that needs to be updated when the ComboBox selects a new element from its DataSource:

textBoxFirstName.DataBindings.Add("Text", PersonList, "FirstName");

The controls are updated automatically.
In the ComboBox SelectedIndexChanged handler, you can set the SelectedPerson property value to the current SelectedItem, casting it to the Person class.

public List<Person> PersonList { get; set; }
public Person SelectedPerson { get; set; }

private void InitializePersonList()
{
    this.PersonList = new List<Person>
    {
        new Person { FirstName = "Bob", LastName = "Builder" },
        new Person { FirstName = "Mary", LastName = "Poppins" }
    };
}

private void InitializeDataBinding()
{
    comboBox.DisplayMember = "FirstName";
    comboBox.DataSource = this.PersonList;

    textBoxFirstName.DataBindings.Add("Text", PersonList, "FirstName");
    textBoxLastName.DataBindings.Add("Text", PersonList, "LastName");
}

private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    this.SelectedPerson = (Person)(sender as ComboBox).SelectedItem;
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
0

Try this

private void InitializeDataBinding()
        {
            SelectedPerson = PersonList[0];

            var bindingSource = new BindingSource();
            bindingSource.DataSource = PersonList;

            comboBox.DisplayMember = "FirstName";
            comboBox.DataSource = bindingSource;

            textBoxFirstName.DataBindings.Add("Text", bindingSource, "FirstName");
            textBoxLastName.DataBindings.Add("Text", bindingSource, "LastName");
        }

private void comboBox_TextChanged(object sender, EventArgs e)
        {
            var selectedPerson = PersonList.FirstOrDefault(x => x.FirstName == comboBox.Text);
            if (selectedPerson == null) return;
            comboBox.SelectedItem = selectedPerson;
        }
NaDeR Star
  • 647
  • 1
  • 6
  • 13