Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combobox doesn't allow enter custom text if DataBinding is used


I have the following class:

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

and I have a form with 2 comboboxes on it. I bind these comboboxes to Address class:

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

The database of Cities and Streets is not complete, so sometimes user should write custom values to combobox. The problem is - having combobox databindings doesn't allow to write custom values to this combobox. Is there a workaround for this behaviour?
Thanks in advance!

like image 295
StuffHappens Avatar asked Mar 29 '11 13:03

StuffHappens


People also ask

Can a user enter custom values in a ComboBox?

Bookmark this question.

How do I disable writing in ComboBox?

We can select any option in the dropdown list. Now add state = "readonly" in the Combobox object, it will make the Combobox Entry Widget disabled.

Which method is used to add the items in a ComboBox * Items insert (); items add (); items set (); items append ();?

// Creating ComboBox using ComboBox class ComboBox mybox = new ComboBox(); Step 2: After creating ComboBox, add the elements in the ComboBox. Step 3: And last add this combobox control to form using Add() method.


2 Answers

This works: (in your case)

Set the DrowdownStyle to Dropdown and bind to the ComboBox's Text property instead of SelectedItem.

For the two comboboxes, you appear to want to bind the text to the City and Street properties of an instance of the Address class. You don't seem to want to append any items in the List<string> returned by the GetCityDataSource() or GetStreetDataSource() methods.

Therefore, since the Text target property of the binding below isn't entangled with the (unchangeable) items collection associated with your datasource, the following modifications should make your code work: (I've verified the essense of the code changes below using 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! The approach above only works when you want to use the City and Street data for simple UI-guidance. You are not establishing a permanent relationship between the address data and the objects for which you register an address. If you want to keep your data normalized then you would wish to store foreign keys to the entries in the City, Street (and perhaps Zipcode) tables.

With user defined street and city names, you will get a lot of fuzzy data (e.g. Washington DC, WASHINGTON D.C., St. Patricks rd., Saint Patrick's road etc.) which in the future will make it difficult to execute SQL queries using WHERE Street = [something]. With normalized data you would simply do a WHERE StreetID = [specificID].

EDIT

If you are trying to do two things at the same time within the same UI dialog (both selection of street and city for e.g. a person/company profile as well as maintenance of your application's internal street and city lists), then you have to use a different approach.

The simplest is probably to add a "new city" and a "new street" button next to your combobox and update the datasource for the combobox when the user has provided the proper input in a dialog.

You could also add a dummy entry to the combobox data source with the string "[add New]", and use special handling when this item is selected. Since this approach involves tampering with the source list for the combo, it can easily get a little messy.

Sample App

A sample form with a databound ComboBox which uses a List<string> data source

enter image description here

Key properties after selecting a predefined street

enter image description here

Key properties after selecting a custom street

enter image description here

like image 71
Simen S Avatar answered Oct 15 '22 16:10

Simen S


Check this out:

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; }
}
like image 39
Mitja Bonca Avatar answered Oct 15 '22 16:10

Mitja Bonca