【问题标题】:Adding items in ListView too slow在 ListView 中添加项目太慢
【发布时间】:2013-04-26 23:13:27
【问题描述】:

我有一个 ListView,并通过循环将项目逐个添加到其中
这个 ListView 有 CheckBoxes

在该循环中,我决定是否应选中复选框
问题是如果要检查的复选框太多,添加项目太慢
这是代码:

for (int i = 0; i < dt.Rows.Count; i++)
{
    DataRow drow = dt.Rows[i];

    // Only row that have not been deleted
    if (drow.RowState != DataRowState.Deleted && int.Parse(drow["season"].ToString()) != 0)
    {
        ListViewItem lvi = new ListViewItem(drow["episode_name"].ToString());

        lvi.SubItems.Add(drow["first_aired"].ToString());
        lvi.SubItems.Add(drow["episode"].ToString());
        lvi.SubItems.Add(drow["season"].ToString());
        lvi.SubItems.Add(drow["rating"].ToString());
        lvi.SubItems.Add(drow["episode_id"].ToString());
        if (bool.Parse(drow["watched"].ToString()))
        {
            lvi.Checked = true; //this is the problem, when i remove it, adding is fast
        }
        else {
            lvi.Checked = false;
        }
        episodesList.Items.Add(lvi);
    }
}

我怎样才能让它更快?

【问题讨论】:

  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • @pedja 你是在计算你的 Db 调用还是只计算循环?
  • 问题是我有更新数据库的 listView_ItemCheck 处理程序,所以每次检查项目时我也会更新数据库
  • 是的,如果它被触发,那肯定会导致问题。请参阅我的回答中的评论以获取解决方法。

标签: c# winforms


【解决方案1】:

在您的列表视图中,在加载结果时调用.BeginUpdate()。完成后,致电.EndUpdate()。这应该会加快速度,因为它不会同时尝试处理和绘制。

// wait to draw
episodesList.BeginUpdate();

// add your items

// draw everything
episodesList.EndUpdate();

编辑

正如贾斯汀建议的那样,AddRange() 可以帮助一些人,但它可能不会消除您的问题。见:How to speed adding items to a ListView?

编辑#2

由于事件处理程序导致问题,您可以通过在加载期间删除处理程序并在之后重新添加它们来解决它们。或者,您可以使用您在加载之前和之后设置的全局布尔值_isLoading,然后您可以在处理程序中检查_isLoading,这样您就不会去数据库了。不过,删除/读取处理程序可能是更清洁的解决方案。

Removing event handlers

【讨论】:

  • 大约 100 左右,添加大约需要 12 秒
  • @pedja 您是否尝试过先将 ListViewItems 填充到列表中,然后使用 listView.AddRange(mylist.ToArray());?
  • 我不认为它快得多,@贾斯汀。如果要相信这个测试,一点点,但不是很多:stackoverflow.com/questions/9008310/…
  • 10 秒添加大约 100 个项目?世界卫生大会?那里有很大的问题,
  • @Matthew Watson 这正是问题所在
【解决方案2】:

通常,当您进行较大更改时,应将mylistview.BeginUpdate() 放在循环之前,然后放在mylistview.EndUpdate()。这将停止更新列表,直到您调用 EndUpdate()。

复选框可能会导致重新绘制列表,从而减慢它必须完成的大量工作。

您可以尝试先创建列表视图项,然后使用 AddRange() 方法将它们添加到列表视图中。 MSDN 将其列为首选方式。

【讨论】:

    【解决方案3】:

    可能是字符串索引器查找导致速度变慢。你能指望索引是静态的吗?您可以尝试将代码替换为整数索引,看看是否会提高性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多