【问题标题】:C# Winform grid rendering slow on Windows 7C# Winform 网格在 Windows 7 上渲染缓慢
【发布时间】:2011-11-16 16:30:13
【问题描述】:

我注意到 C# winform datagrid 在我的 windows 7 64 位机器上非常慢。对于具有 1000 行 + 足够的列/文本以适应屏幕宽度的标准网格,我看到滚动呈现明显延迟(即滚动/滚动条移动滞后约 0.5 秒而不是平滑)。网格在最大化到全屏时特别慢,并且随着显示尺寸的减小而变得更快。

通过将 DataTable 绑定到 DataGridView 实例,GUI 是一个简单的设置;我研究了双缓冲等常见的罪魁祸首,但没有看到太多改进。该机器是 win 7 64 位,Xeon 四核和 2 x 23 英寸屏幕,在 nvidia quadro nvs 420 上。

有人知道为什么会这样吗?

【问题讨论】:

  • 单元格格式等的事件处理程序是什么样的?如果您在那里花费大量时间,则显示更新可能会很慢。加上第一个答案中提到的 AutoSize*Mode。

标签: c# winforms performance


【解决方案1】:

尝试禁用网格的所有事件处理程序,然后查看网格的执行情况。如果它执行良好,请启用一些,直到您遇到性能问题。如果即使网格没有事件处理程序并且它仍然执行缓慢,那么罪魁祸首可能是史蒂夫在他的回答中提到的 AutoSizing。

应用程序性能在任何其他机器上是否会受到影响?是否与需要重新安装视频驱动程序有关?

编辑:我刚刚制作了一个测试应用程序并看到了您的问题,但是当我进行双缓冲时它就消失了? 你是怎么做双缓冲的?

看到这个答案: How to double buffer .NET controls on a form?

我的完整代码,我创建了一个 DataSet 有 20 列,名为 DataSet1,然后我创建了一个简单的 Windows 窗体,并带有 DataGridView

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // comment out the line below for the application to lag
            SetDoubleBuffered(dataGridView1);


            for (int i = 0; i < 10000; i++)
            {
                dataSet1.DataTable1.AddDataTable1Row(GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString(),
                    GetRandomString());
            }
        }

        public static void SetDoubleBuffered(System.Windows.Forms.Control c)
        {
            //Taxes: Remote Desktop Connection and painting
            //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
            if (System.Windows.Forms.SystemInformation.TerminalServerSession)
                return;

            System.Reflection.PropertyInfo aProp =
                  typeof(System.Windows.Forms.Control).GetProperty(
                        "DoubleBuffered",
                        System.Reflection.BindingFlags.NonPublic |
                        System.Reflection.BindingFlags.Instance);

            aProp.SetValue(c, true, null);
        }


        private Random rand = new Random();

        private string validChars = "0123456789abcdefghijklmnopqurstuvwyz";

        private string GetRandomString()
        {
            StringBuilder builder = new StringBuilder();

            char[] c = new char[rand.Next(15,20)];
            for (int i = 0; i < c.Length; i++)
            {
                c[i] = validChars[rand.Next(0, validChars.Length - 1)];
            }

            return new string(c);
        }
    }
}

测试了超过 100,000 条记录,每条记录有 20 列,长度从 15 到 20 不等

【讨论】:

  • 我没有这个网格的任何事件处理程序(除非你在谈论任何继承的处理程序)。在其他机器上性能也很差,但所有类似的操作系统和硬件。
  • 您能详细说明您是如何进行双缓冲的吗?我已将我的答案扩展到似乎可行的工作示例。
  • 我有完全相同的功能来设置双缓冲。
  • 奇怪,我很茫然,因为它在我的 Windows 7 x64 电脑(core2duo 和 Radeon HD 2400 XT)上运行良好。表格是继承的还是什么?您是否尝试过制作一个新的 WinForms 应用程序并执行我上面所做的操作?这工作正常还是运行不佳?
  • 我在一个新的 winform 上测试它。我看到的唯一区别是我只使用 DataTable 并且你有一个 DataSet。我实际上在“dataSet1.DataTable1”上得到了一个构建错误,所以不能完全运行你所拥有的。
【解决方案2】:

您可能需要检查 AutoSizeRowsMo​​de 和 AutoSizeColumnsMode 设置。

有时 AutoSizing 会降低 GUI 的速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2017-01-30
    • 2020-12-06
    相关资源
    最近更新 更多