我正在尝试使用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与数据源绑定,这样我就不能。
如何将数据源设置为像上面的代码一样加载?
答案 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