使用WinForms显示包含大量组合框控件的选项卡速度较慢
我已经设置了一个带有多个选项卡的对话框。其中一个包含20个组合框,每个组合框包含100多个项目,添加方式如下:使用WinForms显示包含大量组合框控件的选项卡速度较慢,winforms,optimization,combobox,performance,Winforms,Optimization,Combobox,Performance,我已经设置了一个带有多个选项卡的对话框。其中一个包含20个组合框,每个组合框包含100多个项目,添加方式如下: foreach (var x in collection) { string text = FormatItem (x); combo.Items.Add (text); } 所以这些东西一点也不新奇。它们是纯字符串,在创建对话框时,组合框会被填充。这几乎是瞬间发生的 然而,当用户第一次单击包含所有这些组合框的选项卡时,GUI会冻结几秒钟(而我正在一台真正健壮的机器上
foreach (var x in collection)
{
string text = FormatItem (x);
combo.Items.Add (text);
}
所以这些东西一点也不新奇。它们是纯字符串,在创建对话框时,组合框会被填充。这几乎是瞬间发生的
然而,当用户第一次单击包含所有这些组合框的选项卡时,GUI会冻结几秒钟(而我正在一台真正健壮的机器上运行)
我加载了System.Windows.Forms
的符号,并试图在程序卡住时闯入调试器。我发现的是具有以下调用的堆栈跟踪:
System.Windows.Forms.Control.CreateHandle()
System.Windows.Forms.ComboBox.CreateHandle()
System.Windows.Forms.Control.CreateControl(...) x 3
System.Windows.Forms.Control.SetVisibleCore(true)
System.Windows.Forms.TabPage.Visible.set(true)
这会导致大量的本机转换,WndProc
调用等。我想每个组合框中的每个项目都会发生这种情况。呸
显然,我无法优化WinForms。但也许我可以采取一些行动来避免在我可怜的GUI上迷失方向?有什么想法吗
Nota bene:
句柄
属性,我会在那一刻支付罚金,而不是在选项卡第一次可见时支付罚金。但是在创建表单时必须等待几秒钟也是不可接受的。我真的很想摆脱漫长的准备时间BeginUpdate
和EndUpdate
的想法在这里并不适用:它们应该用来防止控件在其项目列表被填充时重新绘制。但在我的例子中,问题发生在控件设置好之后你所说的与我所观察到的不一致…: 但是您是否尝试过使用.BeginUpdate/.EndUpdate
您可以尝试的另一件事是在需要之前不填充框。延迟它直到盒子获得焦点,例如。。。(如果捕获下拉事件,某些用户可能会对上/下箭头键不起作用感到恼火。)不是迭代集合,设置ComboBox.DataSource不是一个可行且更快的替代方案吗
comboBox1.DataSource = myCollection1;
comboBox2.DataSource = myCollection2;
comboBox3.DataSource = myCollection3;
// and so on...
下面是一个更完整的示例:
public class Entity
{
public string Title { get; set; }
public override string ToString()
{
return Title;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<Entity> list = new List<Entity>
{
new Entity {Title = "Item1"},
new Entity {Title = "Item2"},
new Entity {Title = "Item3"}
};
comboBox1.DataSource = list;
}
公共类实体
{
公共字符串标题{get;set;}
公共重写字符串ToString()
{
返回标题;
}
}
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
列表=新列表
{
新实体{Title=“Item1”},
新实体{Title=“Item2”},
新实体{Title=“Item3”}
};
comboBox1.DataSource=列表;
}
一个表单上有很多控件可能是个问题。我曾经有一个表单动态创建了50-100个文本框控件。加载速度很慢
我们通过使用datagrid解决了这个问题。它是一个针对大量数据进行优化的控件。我不知道您的确切要求是什么,但它可能会起作用。到目前为止,我尝试的所有操作都失败了,无法加快包含所有组合框的选项卡的第一次显示。数据绑定也没有帮助
最后,我决定通过做一个技巧来解决这个问题,类似于所建议的,即当焦点第一次到达组合时,只填充
项
集合。这仍然会产生明显的延迟,即创建所有项的时间(在开始更新
和结束更新
方法调用对内),但这是可以忍受的(大约200毫秒,而在我最初的场景中是几秒钟)。我刚刚遇到了同样的问题,在组合框中填充大约4000k个项目的速度慢得令人无法接受
我在表单的OnLoad事件处理程序中填充组合,但是,当我将此代码转换为构造函数时,在InitializeComponent()之后,根本没有延迟
我猜在OnLoad中执行此操作会导致重新绘制组合,从而导致延迟?无论如何,我只是想添加此操作,以防在这种情况下对其他人有用。是的,延迟控件项的填充可能会起作用…但这需要相当多的调整,因为我无法使用
selectedIdex
和其他类似属性。我在.Net Framework 4.7中看到了相同的问题!它尚未修复!