【问题标题】:Combobox doesn't allow enter custom text if DataBinding is used如果使用 DataBinding,组合框不允许输入自定义文本
【发布时间】:2011-07-25 06:54:26
【问题描述】:


我有以下课程:

class Address
{
     public string City {get; set;}
     public string Street {get; set;}
}

我有一个带有 2 个组合框的表单。我将这些组合框绑定到地址类:

CityComboBox.DataSource = GetCityDataSource();
StreetComboBox.DataSource = GetStreetDataSource();
Address address = new Address();
CityComboBox.DataBindings.Add("SelectedItem", address, "City");
StreetComboBox.DataBindings.Add("SelectedItem", address, "Street");

城市和街道的数据库不完整,所以有时用户应该将自定义值写入组合框。问题是 - 拥有组合框数据绑定不允许将自定义值写入此组合框。这种行为有解决方法吗?
提前致谢!

【问题讨论】:

  • GetCityDataSource() 返回什么样的集合?

标签: c# winforms data-binding combobox


【解决方案1】:

这行得通:(在你的情况下)

DrowdownStyle 设置为Dropdown 并绑定到组合框的Text 属性而不是SelectedItem

对于这两个组合框,您似乎希望将文本绑定到Address 类实例的CityStreet 属性。您似乎想在GetCityDataSource()GetCityDataSource()GetStreetDataSource() 方法返回的List<string> 中附加任何项目。

因此,由于下面绑定的Text target 属性没有与与您的数据源 关联的 (unchangeable) 项目集合纠缠在一起,因此以下修改应该使您的代码工作:(我已经使用 VS 2010 验证了以下代码更改的本质)。

 CityComboBox.DataSource = GetCityDataSource(); 
 StreetComboBox.DataSource = GetStreetDataSource(); 
 Address address = new Address(); 
 CityComboBox.DropDownStyle = ComboBoxStyle.DropDown
 CityComboBox.DataBindings.Add("Text", address, "City");
 StreetComboBox.DropDownStyle = ComboBoxStyle.DropDown
 StreetComboBox.DataBindings.Add("Text", address, "Street");

PS!仅当您想将城市和街道数据用于简单的 UI-指导时,上述方法才有效。您没有在地址数据和您为其注册地址的对象之间建立永久关系。如果您希望保持数据规范化,那么您可能希望将外键存储到 City、Street(可能还有 Zipcode)表中的条目中。

使用用户定义的街道和城市名称,您将获得大量模糊数据(例如Washington DCWASHINGTON D.C.St. Patricks rd.Saint Patrick's road 等),这将使将来难以执行 SQL使用WHERE Street = [something] 查询。使用标准化数据,您只需执行WHERE StreetID = [specificID]

编辑

如果您尝试在同一个 UI 对话框中同时进行两件事(选择街道和城市,例如个人/公司简介以及 维护应用程序的内部街道和城市列表),那么您必须使用不同的方法。

最简单的可能是在您的组合框旁边添加一个“新城市”和一个“新街道”按钮,并在用户在对话框中提供正确输入后更新组合框的数据源。

您还可以使用字符串“[add New]”向组合框数据源添加一个虚拟条目,并在选择此项时使用特殊处理。由于这种方法涉及篡改组合的源列表,因此很容易变得有点混乱。

示例应用

带有数据绑定 ComboBox 的示例表单,它使用 List<string> 数据源

选择预定义街道后的关键属性

选择自定义街道后的关键属性

【讨论】:

    【解决方案2】:

    看看这个:

    public partial class Form1 : Form
    {
        BindingList<Address> list;
        public Form1()
        {
            InitializeComponent();
    
            list = new BindingList<Address>();
            //lets add some example data:
            list.Add(new Address{ City = "London", Street = "Street 111" });
            list.Add(new Address { City = "Barcelona", Street = "Street 222" });
            comboBox1.DataSource = list;
    
            //I am not sure what you want to show (and what to use as a value). You can change this!
            comboBox1.DisplayMember = "Street";
            comboBox1.ValueMember = "City";
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            //adding new object to the list:
            string _city = textBox1.Text;
            string _street = textBox2.Text;
            if (_city != String.Empty && _street != String.Empty)
            {
                list.Add(new Address { City = _city, Street = _street });
                textBox1.Text = "";
                textBox2.Text = "";
            }
        }
    }
    
    class Address
    {
        public string City { get; set; }
        public string Street { get; set; }
    }
    

    【讨论】:

    • 什么是 textBox1?这里绑定在哪里?
    【解决方案3】:

    您必须将新值插入数据源(如果这是一个数组,请调整数组的大小,并在新索引处添加新值,如果这是一个通用列表,只需向其中添加新项目)。

    【讨论】:

    • 我应该处理什么事件才能做到这一点?有没有更简单的方法?
    【解决方案4】:

    我是怎么做的(我不使用数据绑定):

    • 初始化List&lt;T&gt; 的实例(在您的情况下可以是List&lt;Address&gt;)。
    • 将数据库项读入List&lt;T&gt;
    • 使用List&lt;T&gt; 中的项目填充组合框。
    • 创建新项目后,将该项目插入数据库。
    • 在顶部重新启动(适用于您可以随时调用的过程)。

    如果您必须进行数据绑定,您可以隐藏组合框并弹出一个文本框,直到用户保存您的信息,但您仍然需要写入数据库并再次读取数据。

    【讨论】:

      【解决方案5】:

      您也许可以处理键事件,当他们开始输入时添加一个新元素?

      【讨论】:

      • 我到底应该怎么做?例如,当用户输入 New Yourk 时,我应该添加新的 Cities N, Ne, New, New, New Y, ...?
      • 使用组合框的离开事件确认文本到数据源。键入时保留对数据源中当前正在编辑的项目的引用。
      【解决方案6】:

      问题是 - 有组合框 数据绑定不允许写入 此组合框的自定义值。是 这种行为有解决方法吗?

      所以不要绑定它! 编写您自己的方法来填充组合框和用于编辑项目的事件处理程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-16
        • 2014-06-18
        • 2012-04-17
        • 1970-01-01
        相关资源
        最近更新 更多