当前位置:  开发笔记 > 编程语言 > 正文

在我的两个屏幕之一上可怕的重绘DataGridView性能

如何解决《在我的两个屏幕之一上可怕的重绘DataGridView性能》经验,为你挑选了5个好方法。

您只需要根据DataGridView创建一个自定义类,以便启用其DoubleBuffering.而已!

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    } 
}

只要我的所有网格实例都使用这个自定义版本,一切都很好.如果我遇到由此引起的情况,我无法使用子类解决方案(如果我没有代码),我想我可以尝试将该控件注入表单:)(虽然我'将更有可能尝试使用反射来强制从外部启用DoubleBuffered属性再次避免依赖).

令人遗憾的是,这么简单的事情花了我很多时间......

注意:将答案作为答案,以便将问题标记为已回答



1> Benoit..:

您只需要根据DataGridView创建一个自定义类,以便启用其DoubleBuffering.而已!

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    } 
}

只要我的所有网格实例都使用这个自定义版本,一切都很好.如果我遇到由此引起的情况,我无法使用子类解决方案(如果我没有代码),我想我可以尝试将该控件注入表单:)(虽然我'将更有可能尝试使用反射来强制从外部启用DoubleBuffered属性再次避免依赖).

令人遗憾的是,这么简单的事情花了我很多时间......

注意:将答案作为答案,以便将问题标记为已回答



2> Brian Ensink..:

下面是一些使用反射设置属性的代码,没有像Benoit建议的子类化.

typeof(DataGridView).InvokeMember(
   "DoubleBuffered", 
   BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
   null, 
   myDataGridViewObject, 
   new object[] { true });


乐意效劳!我几乎没有发布它,因为这个问题已经有一年了.

3> GELR..:

对于在VB.NET中搜索如何操作的人,这里是代码:

DataGridView1.GetType.InvokeMember("DoubleBuffered", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.SetProperty, Nothing, DataGridView1, New Object() {True})



4> 小智..:

添加到以前的帖子,对于Windows窗体应用程序,这是我用于DataGridView组件以使它们快速的.DrawingControl类的代码如下.

DrawingControl.SetDoubleBuffered(control)
DrawingControl.SuspendDrawing(control)
DrawingControl.ResumeDrawing(control)

在构造函数中的InitializeComponent()之后调用DrawingControl.SetDoubleBuffered(control).

在进行大数据更新之前调用DrawingControl.SuspendDrawing(控件).

在进行大数据更新后调用DrawingControl.ResumeDrawing(控件).

最后2个最好用try/finally块完成.(或者甚至更好地重写类,IDisposableSuspendDrawing()在构造函数ResumeDrawing()中调用Dispose().)

using System.Runtime.InteropServices;

public static class DrawingControl
{
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

    private const int WM_SETREDRAW = 11;

    /// 
    /// Some controls, such as the DataGridView, do not allow setting the DoubleBuffered property.
    /// It is set as a protected property. This method is a work-around to allow setting it.
    /// Call this in the constructor just after InitializeComponent().
    /// 
    /// The Control on which to set DoubleBuffered to true.
    public static void SetDoubleBuffered(Control control)
    {
        // if not remote desktop session then enable double-buffering optimization
        if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
        {

            // set instance non-public property with name "DoubleBuffered" to true
            typeof(Control).InvokeMember("DoubleBuffered",
                                         System.Reflection.BindingFlags.SetProperty |
                                            System.Reflection.BindingFlags.Instance |
                                            System.Reflection.BindingFlags.NonPublic,
                                         null,
                                         control,
                                         new object[] { true });
        }
    }

    /// 
    /// Suspend drawing updates for the specified control. After the control has been updated
    /// call DrawingControl.ResumeDrawing(Control control).
    /// 
    /// The control to suspend draw updates on.
    public static void SuspendDrawing(Control control)
    {
        SendMessage(control.Handle, WM_SETREDRAW, false, 0);
    }

    /// 
    /// Resume drawing updates for the specified control.
    /// 
    /// The control to resume draw updates on.
    public static void ResumeDrawing(Control control)
    {
        SendMessage(control.Handle, WM_SETREDRAW, true, 0);
        control.Refresh();
    }
}



5> Kev..:

答案对我也有用.我想我会添加一个改进,我认为应该是实施解决方案的任何人的标准做法.

该解决方案很有效,除非在远程桌面下作为客户端会话运行UI,尤其是在可用网络带宽较低的情况下.在这种情况下,通过使用双缓冲可以使性能变差.因此,我建议以下作为更完整的答案:

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        // if not remote desktop session then enable double-buffering optimization
        if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
            DoubleBuffered = true;
    } 
}

有关更多详细信息,请参阅检测远程桌面连接

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有