如何将 WinForms ComboBox 的 SelectedItem 数据绑定到 TextBox

How to databind the SelectedItem of a WinForms ComboBox to a TextBox

代码

我有这个UI

使用此代码

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}";
        }
    }
}

问题

我有两个关于数据绑定的问题:

  1. 当我 select Mary 在 ComboBox 中时,两个 TextBox 控件没有得到更新。这是为什么?我做错了什么?

  2. 当我更改 ComboBox 中的文本 "Mary" 时,SelectedPerson 对象不会更新为来自 ComboBox 的新 FirstName,例如 "Mary changed"。我将如何实现更改 ComboBox FirstName 以更新 SelectedPerson 的 FirstName 的行为?还是 ComboBox 不可能做到这一点?

其他实验

如果我需要向问题添加更多详细信息,请告诉我。

您不需要 SelectedPerson 变量。看起来您只是连接了错误的数据源。试试这样:

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

你只需要将ComboBox.DataSource设置为List<Person>对象,这里用PersonList属性表示。
当 ComboBox 从其 DataSource 中选择一个新元素时,向需要更新的控件添加一个 DataBinding

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

控件会自动更新。
在 ComboBox SelectedIndexChanged 处理程序中,您可以将 SelectedPerson 属性 值设置为当前 SelectedItem,将其转换为 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;
}

试试这个

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;
        }