【问题标题】:Super slow C# custom control超慢C#自定义控件
【发布时间】:2010-10-09 22:14:33
【问题描述】:

我制作了一个自定义控件,它是一个 FlowLayoutPanel,我在其中放入了一堆其他自定义控件(只是按钮,每个都有三个标签和一个图片框覆盖)

大约 100 个按钮可以正常工作,但如果增加到 1000 个按钮,就会遇到麻烦。将其提高到 5000,它会在 20 秒后死亡。

我的自定义代码很少,我明智地使用了暂停和恢复布局。

那我做错了什么?我确信我的(相当快速的)计算机应该能够处理几千个按钮和标签。

(我对 C# GUI 的东西还很陌生,所以也许我应该做一些完全不同的事情。)

编辑 1:

这几乎是目前唯一的自定义代码:

flowLayoutPanel1.SuspendLayout();
foreach (DataRow row in dt.Rows) // dt is from a DB query
{
    flowLayoutPanel1.Controls.Add(new PersonButton(row));
}
flowLayoutPanel1.ResumeLayout();

在 PersonButton 构造函数中:

this.label1.Text = row["FirstName"].ToString().Trim() + " "
    + row["Surname"].ToString().Trim();

(应该还附上一张图片,但我不确定是否有人能看到。)

编辑 2:

我想我真的应该使用 DataGridView 或 ListView,但我想要的不仅仅是一行文本和每行一个小图标;我希望它看起来类似于 Firefox 中的下载视图(Ctrl + J)。 (见截图)

非常感谢您的所有意见,顺便说一句。我想我得重新考虑......

alt text http://img156.imageshack.us/img156/1057/capture.png

【问题讨论】:

  • 您确定这是自定义控件,而不是用户控件吗?听起来您制作了一个用户控件。
  • 你做错了什么?您正在创建数千个控件。可能有更好的方法来做你想做的事情。
  • “那我做错了什么?”在表单上显示 1000 个按钮。
  • 尝试使用页面导航概念

标签: c# optimization user-controls


【解决方案1】:

试试这个;将此方法放入您的代码中。

受保护的覆盖 CreateParams CreateParams { 得到 { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; 返回cp; } }

【讨论】:

    【解决方案2】:

    [死灵模式=开启]

    您有 1000 行数据,但您只能显示其中的一小部分,因此请仅创建可见的控件,并在滚动时重复使用它们并使用新数据更改其内容。

    【讨论】:

      【解决方案3】:

      听起来你真的需要重新考虑你的界面。

      就像其他人提到的那样,表单上的控件数量将不可用。

      但是,我已经做了一些实验,以查看在代码中创建新控件的时间,甚至使用反射,并发现在流布局面板中动态创建的数百个数据绑定控件应该在 1 到 2 秒内创建.

      发布更多代码示例可能有助于获得更好的答案。

      更多信息:我刚刚重新运行了计时测试,300 个控件用了 0.5 秒,400 个用了 1.9 秒,600 个用了 3 秒,1000 个用了 6 秒。
      似乎在 300 到 400 之间有一个限制,资源开始被过度使用。

      【讨论】:

        【解决方案4】:

        5k 控件所需的布局逻辑对于任何类型的包装面板来说都太多了。您可能想研究一种不同类型的控件,该控件设计了保存数千个条目 - 类似于 DataGridView

        DataGridView 有几个不同的column types 可用,它们应该适用于您正在显示的数据类型(图像、按钮、标签)。由于您的数据库查询看起来返回一个 DataTable,您可以简单地 bind that directly to your DataGridView 并删除循环。

        【讨论】:

          【解决方案5】:

          如果有 1000 多个按钮,您的应用程序的 GDI 资源和/或原始句柄可能会非常低。

          不确定您的应用程序应该做什么,但网格或组合框可能是更好的选择。

          【讨论】:

            【解决方案6】:

            C# WinForm 应用程序可以处理 1000 个任何类型控件的实例吗?我不是 WinForm Guru,但您对您的应用程序的期望可能是不合理的。

            您想要显示 1000 多个任何类型的控件这一事实可能表明您正在从错误的方向进行软件设计。

            【讨论】:

            • 我担心这会是答案:)
            • 同意!为什么要在一个表单上显示 1000 个控件?
            • +1 Matthew,如何要求用户跟踪 5000 个不同的按钮?
            • +1。这属于 Raymond Chen 的“如果你不得不问,你可能做错了”规则:tinyurl.com/d27sdt。可用性是关键:几乎没有理由在页面上显示 1000 多个控件。这么多数据会让用户不知所措。
            • 你们没玩过专家级别的扫雷吧?
            【解决方案7】:

            您必须发布一些布局代码,否则我们将无法提供太多/根本帮助。

            此外,您最好的第一选择是分析您的代码。分析是找出代码中究竟是什么执行缓慢的唯一可靠方法。根据我的经验,UI 代码尤其如此。

            【讨论】:

            • 我应该在 cmets 中发布布局代码吗? flowLayoutPanel1.SuspendLayout(); foreach(dt.Rows 中的 DataRow 行) { flowLayoutPanel1.Controls.Add(new PersonButton(row)); } flowLayoutPanel1.ResumeLayout();这是唯一的自定义代码。除了改变标签的 PersonButton 构造函数。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-23
            相关资源
            最近更新 更多