-2

I am working on a Time Converter, which has 2 Comboboxes, To and From.

Both Combobox has a BIG list of about 20K+ of countries and cities name.

This list is hard coded in the Code itself, and I'm using this code:

this.comboBox_TO.Items.AddRange(new object[]
{
 "Afghanistan, Kabul",
  //List
}

this.comboBox_FROM.Items.AddRange(new object[]
{
 "Afghanistan, Kabul",
  //List
}

The issue here is this code takes a lot of time to add the BIG list into Combobox and resets everytime time converter is closed. So, next time I reopen Time converter, it takes lots of time again.

I need the help in either,

  1. Fastest way to add list into Combobox Items, OR
  2. Stop Combobox resetting everytime converter is reopened.

Thanks in advance.

Tân
  • 1
  • 15
  • 56
  • 102
Ankur Gupta
  • 41
  • 10
  • 2
    You need to change your design as soon as possible. Storing 20K items in a combobox is a user interface nightmare. Don't do it – Steve Mar 01 '17 at 11:42
  • 1
    1. Why do you hardcode 20000 cities? Export them to an XML file so that you can edit it when you need. 2. No user will scroll and look through 20000 combobox items to find his city - introduce a search input field with dropdown limited to 10-20 matching items, so that a user starts entering city / country name and then selects the matching if found. – Yeldar Kurmangaliyev Mar 01 '17 at 11:43
  • 4
    You can try splitting combobox into two: *country* combobox (about `200` items) and *city in the country* combobox (about `100` items) – Dmitry Bychenko Mar 01 '17 at 11:43
  • Combo box is made for few records...you need to change your logic – Almeida Mar 01 '17 at 11:52

2 Answers2

1

If you have only a string array, you can simply assign it as the DataSource property of the ComboBox.

String[] myArray = { "One", "Two", "Three" };
this.comboBox_FROM.DataSource = myArray;

As others have pointed out, you should only populate combobox with a few items, probably not more than 100 - 1000 at a time. Then search and populate as the user types.

You can use a Hashset to load up the data when your application starts, then populate combo on textchange/slight delay. See this answer for example implementation

Community
  • 1
  • 1
Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
0

Why not using a DataGridView

Create a class that hold the information that you need like this:

public class CityListItems
{
    public string Name { get; set; }
    public CityListItems(string n)
    {
        this.Name = n;
    }
    // just for completeness, if you really intend to use ComboBox or ListBox
    public override string ToString()
    {
        return this.Name;
    }
}

Here is a test with time measurement. Just copy it into a Winforms project with 2 ComboBoxes, 2 ListBoxes, 2 DataGridViews and a TextBox with the corresponding names. And see the time difference for yourself.

public partial class Form2 : Form
{
    List<CityListItems> valuesTo = new List<CityListItems>();
    List<CityListItems> valuesFrom = new List<CityListItems>();
    Stopwatch sw = new Stopwatch();

    public Form2()
    {
        InitializeComponent();

        sw.Start();

        for (int i = 0; i < 30000; i++)
        {
            valuesTo.Add(new CityListItems("TO Value " + i));
        }

        for (int i = 0; i < 30000; i++)
        {
            valuesFrom.Add(new CityListItems("From Value " + i));
        }

        // just uncomment the part that you would like to measure
        // and comment out the other 2

        //comboBox1.Items.AddRange(valuesTo.ToArray());
        //comboBox2.Items.AddRange(valuesFrom.ToArray());

        //listBox1.DataSource = valuesTo;
        //listBox2.DataSource = valuesFrom;

        dataGridView1.DataSource = valuesTo;
        dataGridView2.DataSource = valuesFrom;
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        sw.Stop();
        textBox1.Text = "TIME: " + sw.ElapsedMilliseconds;
    }
}

The results on my machine:

ComboBox: TIME: 3774

ListBox: TIME: 2459

DataGridView: TIME: 70

Community
  • 1
  • 1
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76