3

我有一个 ComboBox,当我重新填充它时,这似乎是一项相当耗时的任务。在进行了一些分析之后,我发现大部分时间都花在了 ComboBox.Items.AddRange(Array) 方法上。我在下面包含了一个示例方法,它显示了我如何执行 ComboBox 的重新填充。

public void Repopulate(IList<MyType> sortedList)
{
    MyComboBox.BeginUpdate();

    try
    {
        MyComboBox.Items.Clear();
        MyComboBox.Items.AddRange(sortedList.ToArray());
    }
    finally
    {
        MyComboBox.EndUpdate();
    }
}

sortedList 包含大约 280 个项目,最多有 53 个 ComboBox 需要重新填充。因此,重新填充所有这些控件可能需要相当长的时间(在高规格机器上大约 700 毫秒,在低规格机器上大约 8000 毫秒),这对于我的要求来说太慢了。我尝试将 sortedList 添加到新的 IList 中,这大约需要 1 毫秒(在我的高规格机器上)。

我需要重新填充 ComboBox 以便花费更少的时间,理想情况下与 IList 的时间相似,但任何性能提升都会很好。到目前为止,我一直无法找到任何方法来提高重新填充的速度。

有没有人知道如何减少重新填充 ComboBox 所需的时间?

4

4 回答 4

1

您的问题可能是您启用了组合框的Sorted属性。启用此选项后,您调用AddRange组合框会对所有这些项目进行排序,如果您的项目已经排序,则不需要。

为了证明我的观点,我创建了两个组合框,它们使用 10,000 个排序的整数和AddRange. 唯一的区别是一个组合框Sorted启用了该属性,而另一个没有。以下是结果AddRange调用的时间(以毫秒为单位)

notSortedCombo: 5ms
sortedCombo: 1140ms

这可能是你的问题吗?你能有 53 个启用了 sorted 属性的组合框吗?

于 2012-05-16T13:20:10.587 回答
1

AddRange已经调用BeginUpdate并且EndUpdate在引擎盖下,所以你自己调用它并没有获得任何东西。

这为我节省了几毫秒:

public void Repopulate(IList<string> sortedList) {
  comboBox1.BeginUpdate();
  comboBox1.Items.Clear();
  foreach (string item in sortedList) {
    comboBox1.Items.Add(item);
  }
  comboBox1.EndUpdate();
}

更大的问题可能是设计:53 个组合框是向用户抛出的大量组合框——用户将无法同时与所有 53 个控件进行交互。您可能会有点 hacky,只需使用可见值(1 项)填充组合框,然后在控件获得焦点或在后台计时器中填充列表。

但考虑减少屏幕上的控件数量。空白被认为是一件好事。

于 2012-05-16T13:38:15.307 回答
0

您可以通过将FormattingEnabled组合框的属性更改为False

问题是 Visual Studio 保持它就True好像您没有在设计器中“手动”指定项目,而是以编程方式添加它们。

试试,它为我解决了问题

于 2013-02-03T10:47:26.273 回答
0

关于 UI 虚拟化:WPF(示例)和 WinForms 都存在虚拟化。但只有一些控件支持它,如 ListView、DataGridView、TreeView 等。这些是为更大量数据设计的控件。如果可能,您可以切换到这些控件之一。

所有控件是否同时在屏幕上可见?也许只有更新可见的会有所帮助。

另一种方法是异步更新组合框。如果你有幸在 .NET 中使用新的 async/await 东西,这很容易做到。如果您想手动执行此操作,您可以只更新一个组合框并在未来几毫秒安排下一个组合框的更新(使用计时器或 TPL)。这样,UI 至少在更新发生时仍然响应。

还有一种方法是仅当用户关注某个 ComboBox 时才更新列表。通常不需要更新内容,因为用户只有在使用 ComboBox 时才会看到它。

您还可以尝试在更新其数据之前隐藏组合框。或者您可以告诉 Windows 在修改内容时不要重绘 UI(此处为 StackOverflow 主题)。但我还没有测试这是否真的能提高性能。

于 2012-05-16T15:39:28.133 回答