winforms 为什么DataGridView(重新)绘制速度如此缓慢?

q8l4jmvw  于 2022-11-17  发布在  其他
关注(0)|答案(2)|浏览(203)

我知道在SO中有几个关于缓慢的DataGridView的问题,但是我真的尝试了那里提到的所有东西,大多数都是关于更复杂的数据绑定的。
我以前做的事:

  • 我测试了DataTable作为数据源
  • 未绑定的Datagridview,在循环中填充
  • 使用autoColumnResizing等测试了许多设置。所有测试都太慢。

这个例子只是一个主窗体中的datgridview,来自设计者工具箱的普通股票,编辑关闭。

即使它只有100行,它感觉非常滞后时,滚动和重画,它的最大一个核心。
在数据网格视图中滚动时,我执行了VS分析器会话:

我想更深入地挖掘和了解究竟是什么使这个控件如此缓慢,可以做什么来加速它,或者我可以使用什么替代方案来获得一个快速的表,它能够通过单击列标题排序。

public partial class Form1 : Form
{
   List<Record> myData;
    public Form1()
    {
        InitializeComponent();
        myData = getListofRecord();

        dataGridView1.DataSource = myData;
    }

    private static List<Record> getListofRecord()
    {
        var myTable = new List<Record>();
        for (int i = 0; i < 500; i++)
        {
            myTable.Add(new Record() { a = 121+i, b = 123.2434F, c = 2342, d = 312+i*2, e = 123343, f = 12323 });
        }
        return myTable;
    }

}

public class Record
{
    public Single a { get; set; }
    public Single b { get; set; }
    public Single c { get; set; }
    public Single d { get; set; }
    public Single e { get; set; }
    public Single f { get; set; }

}

编辑:
两天后,我在同一台机器上重新运行测试应用程序时得到了不同的结果。它的速度和我预期的一样快,分析可能会导致原因?在hotpath堆栈中,CreateSemiCompatibleDIB丢失。

编辑2:
无论第一个差异背后的真正原因是什么,**通过反射打开双缓冲的效果最明显,速度大约快20倍。**我在其他DGV问题中看到过这些建议,但我只希望获得轻微的视觉改善,而不是全新的体验。
分析热路径现在显示完全不同的调用栈。

编辑3
为了保存我在这个问题中的分析工作,并且不被删除为重复,我想得到一些目标数字,以毫秒为单位,用于重绘DGV。我需要在哪里放置秒表来得到这些数字?

q43xntqr

q43xntqr1#

就这么简单,感谢TaW:

using System.Reflection;

static void SetDoubleBuffer(Control dgv, bool DoubleBuffered)
{
    typeof(Control).InvokeMember("DoubleBuffered", 
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, 
        null, dgv, new object[] { DoubleBuffered });
}

和VB.NET:

Public Sub DoubleBuffered(ByVal dgv As DataGridView, ByVal setting As Boolean)
      Dim dgvType As Type = dgv.[GetType]()
      Dim pi As PropertyInfo = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic)
      pi.SetValue(dgv, setting, Nothing)
   End Sub
tf7tbtn2

tf7tbtn22#

如果有人像我一样,即使做了所有建议的事情,也找不到合适的解决方案,我写这篇文章作为答案。我也有同样的问题,也尝试了所有建议的事情,但没有一个工作,甚至DoubleBuffered。然后我意识到这是因为我正在处理DataGridView1.CellPainting事件。如果有人像我一样挣扎,这可能是因为一个处理的DataGridView事件,特别是Cell事件,会极大地降低DataGridView的速度。因此,我建议尝试摆脱这些处理过的事件。这种方法对我很有效。

相关问题