使ComboBox数据源设置加载异步

时间:2015-09-25 01:50:32

标签: c# winforms performance asynchronous combobox

我正在尝试使用50.000项填充comboBox。

问题是......将所有项目加载到GUI中需要花费太多时间。

所以我试图填充asyncronous:

首先我创建数据源数组:

  var source = Enumerable.Range(1, 50000).Select(e => new{ID = e}).ToArray();

然后我设置了comboBox的datasource属性:

  BeginInvoke(new Action(() => comboBox1.DataSource = source));

上面代码行的问题需要花费很多时间才能完成,并且Window正在冻结。

我正在使用的解决方法是将数据源设置为null并在foreach语句中添加项目并每次调用 Application.DoEvents()

        comboBox1.DataSource = null;
        foreach (var e in source)
        {
            comboBox1.Items.Add(e);
            Application.DoEvents();
        }

它工作正常,但我需要将comboBox与数据源绑定,这样我就不能。

如何将数据源设置为像上面的代码一样加载?

2 个答案:

答案 0 :(得分:0)

包含100个项目的组合框是一个坏主意,但如果你坚持填充5000 ...

获得好的旧backgroundworker并将其连接起来以加载数据源,无论它是哪个对象,都可以说是一个数组。在伪代码中(这些方法可能有参数)

void DoWork() // handles loading of an array
{ 
    // load array here. cbo is disabled 
    myArrayOfValues = <whatever you get from DB>
    foreach var item in myArrayOfValues 
    {

        // here call `worker.Progress` and pass your item in argument
    }
}

void OnWorkComleted(....) 
{ 
   // Set your combo as disabled initially, so people can't click while it is loading


    cbo.Enabled = true;

}

void OnWorkerProgress(....) 
{ 
    // Add items one by one
    cbo.Items.Add(myValue);

}

我没有测试过,但应该可以使用。我喜欢后台工作者,因为它解决了控制和后台线程的问题。否则你将不得不处理if invokeRequired等。这里处理异步作业和控件的这部分是为你抽象的。

添加没有数据源的项目

class Itm
{
    string A {get; set;}
    string B {get; set;}
    string C {get; set;}
}


void Setup()
{
    for (int i = 1; i < 4; i++)
    {
        cbo.Items.Add(new itm { a = "A" + i, b = "B" + i, c = "C" + i});
    }
    cbo.DisplayMember = "A";
    cbo.ValueMember = "B";
}


void OnSelectedIndexChanged(....)
{
     if (cbo.SelectedIndex > -1)
     {
         var item = (itm)cbo.SelectedItem;
         MessageBox.Show(string.Format("Selected: {0}, {1}, {2}", item.A, item.B, item.C));
     }
}

答案 1 :(得分:0)

我不确定这对您的情况是否有帮助,但如果您重新设置DisplayMember和ValueMember,请确保始终设置DataSource。 产生巨大的变化。 更多信息:Link