如果使用DataBinding,Combobox不允许输入自定义文本

时间:2011-03-29 13:11:09

标签: c# winforms data-binding combobox


我有以下课程:

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

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

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

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

6 个答案:

答案 0 :(得分:14)

这有效:(在您的情况下)

DrowdownStyle设置为Dropdown并绑定到ComboBox的Text属性,而不是SelectedItem

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

因此,由于下面绑定的Text 目标属性不与与您的数据源关联的(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等)未来将使用WHERE Street = [something]执行SQL查询变得困难。使用标准化数据,您只需执行WHERE StreetID = [specificID]

修改

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

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

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

示例应用

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

enter image description here

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

enter image description here

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

enter image description here

答案 1 :(得分:1)

检查出来:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

  

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

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