使用双缓冲技术解决winform窗体控件卡顿(dataGridView加载数据缓慢)

简介: 使用双缓冲技术解决winform窗体控件卡顿(dataGridView加载数据缓慢)

背景:在做C/S项目中,做好的窗体出现了页面加载控件缓慢,放大、缩小窗体之后,窗体加载卡顿,以及数据渲染缓慢。


10487add2e4c77d95b7c8fc02592e3d9_f72bbf4b4e314038a1670b6117f51263.png


可以利用双缓冲技术去解决这个问题。那么什么是双缓冲?


百度介绍:我们看电视时,看到的屏幕称为OSD层,也就是说,只有在OSD层上显示图像我们才能看到。现在,我需要创建一个虚拟的、看不见但是可以在上面画图(比如说画点、线)的OSD层,我称之为offscreen(后台缓冲区)。这个offscreen存在于内存中,我们在上面画图,这个offscreen上面的东西可以显示在OSD层上,需要一个创建这个offscreen的函数,返回这个offscreen的句柄(整型指针)、宽度、高度、指向新建offscreen数据缓冲区的指针,该缓冲区是一个在函数外创建的offscreen的数据缓冲区,大小是offscreen的高度*宽度*每个像素点数据的大小。闪烁是图形编程的一个常见问题。需要多重复杂绘制操作的图形操作会导致呈现的图像闪烁或具有其他不可接受的外观。双缓冲的使用解决这些问题。双缓冲使用内存缓冲区来解决由多重绘制操作造成的闪烁问题。当启用双缓冲时,所有绘制操作首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完成后,内存缓冲区直接复制到与其关联的绘图图面。因为在屏幕上只执行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁。


总而言之:在计算机中,动画被视为一种变化的图像序列,由一帧一帧的动态图像组成,这些图像随着时间的改变而改变,后一帧图像是对前一帧图像所作的修改。


在单缓冲动画中,图形直接绘制在显示缓冲区,如果显示后一帧图像,必须擦除屏幕,所以在制作过程中需要不断擦除屏幕,这也是屏幕闪烁(窗体加载缓慢)的原因。双缓冲动画有两个缓冲区,除了有显示缓冲区外,还有内存缓冲区,在制作过程中首先把图形绘制在内存缓冲区中,然后讲内存缓冲区中的图像一次性拷贝到心事缓存区,显示缓冲区只是作为内存缓冲区的一个映像。


举例:


投影仪和白板。但缓冲动画:在使用白板的时候,如果写满了,需要写下一页,那么我只能把白板上的内容擦除掉,再去写内容。双缓冲动画:投影仪的时候是需要需要换内容,我直需要把投影仪中的内容进行修改即可,避免擦除操作。


8a3659e34ff2e6c934275723b1f3e6e7_feecd4ae21e44f2fa9bf9f11315d39b0.png


具体方法(代码展示)


1、 C# winform窗体卡顿的解决办法


哪个窗体需要修改页面卡顿,加入此方法


protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

该方法是可以解决页面上所有控件加载慢的方法。


在上面的代码中,有用到CreateParams 类,它是具体解决卡顿、闪屏的问题。查阅资料:窗体和控件的属性CreateParams,通过它你能够很方便的控制窗体或控件诸如边框、最大化、最小化关闭,按钮的隐藏、窗体的模式化,弹窗模式等的一些特性


2、那么针对dataGridView加载数据慢,不流畅的现象也可以用以下方法。根源上也是利用了双缓冲技术。


需要在窗体所对应的构造构造函数中写入以下代码,控制DataGridView加载数据延迟的问题。

this.SetStyle(ControlStyles.OptimizedDoubleBuffer //双缓冲
                | ControlStyles.ResizeRedraw 
               | ControlStyles.AllPaintingInWmPaint, //不擦除背景,减少闪烁
                true);
            this.UpdateStyles();
            //利用反射设置DataGridView的双缓冲
            Type dgvType = this.dgvwCustomerManagement.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
               BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(this.dgvwCustomerManagement, true, null);

相关文章
|
C# 图形学 Windows
Winform控件优化之背景透明那些事2:窗体背景透明、镂空穿透、SetStyle、GDI透明效果等
两行代码就能实现Form窗体的(背景)透明效果,它不是Opacity属性的整个窗体透明,`TransparencyKey`实现窗体的透明、窗体中间部分镂空效果...
4644 0
Winform控件优化之背景透明那些事2:窗体背景透明、镂空穿透、SetStyle、GDI透明效果等
|
C# 索引 Windows
Winform控件优化之TabControl控件的使用和常用功能
TabControl是一个分页切换(tab)控件,不同的页框内可以呈现不同的内容,将主要介绍调整tab的左右侧显示、设置多行tab、禁用或删除tabpage、隐藏TabControl头部的选项卡等
8270 0
Winform控件优化之TabControl控件的使用和常用功能
|
前端开发 API C#
C#使用外部字体、嵌入字体到程序资源中(Winform)及字体的版权问题
应用程序能够使用一个好的字体,是用户界面很重要的一部分,但是很多字体如果系统没有安装,则需要额外引入,这就涉及到极其重要的字体版权问题,及额外字体的使用和安装。最好的方式应该是将字体嵌入到程序中...
5944 1
C#使用外部字体、嵌入字体到程序资源中(Winform)及字体的版权问题
C#学习相关系列之多线程---ConfigureAwait的用法
C#学习相关系列之多线程---ConfigureAwait的用法
641 0
|
API C# Windows
Winform控件优化之无边框窗体及其拖动、调整大小和实现最大最小化关闭功能的自定义标题栏效果
Winform中实现无边框窗体只需要设置FormBorderStyle = FormBorderStyle.None,但是无边框下我们需要保留移动窗体、拖拽调整大小、自定义美观好看的标题栏等...
5623 0
Winform控件优化之无边框窗体及其拖动、调整大小和实现最大最小化关闭功能的自定义标题栏效果
|
Windows
Winform控件优化之背景透明那些事1:Button控件等背景透明
WinForm不支持真正的透明,其控件透明的实现都是背景颜色设置和对应位置的父控件背景相同。 Winform中控件的背景透明只有三种:Button控件的透明、其他控件的透明...
3846 0
Winform控件优化之背景透明那些事1:Button控件等背景透明
|
小程序 C#
C#WinForm实现Loading等待界面
上篇博客中解决了程序加载时屏幕闪烁的问题。 但是,加载的过程变得很缓慢。 这个给用户的体验也不是很好,我这里想加一个Loading的进度条。 项目启动的时候,加载进度条,界面UI加载完毕,进度条消失。
876 0
|
C# 容器
Winform控件优化之TabControl控件的美化和功能扩展
在基本的TabControl控件使用和功能之上,可以尝试对其进行美化和功能扩展,比如动态删除或添加tab、绘制图标按钮及鼠标hover时的背景变化、Tab从右向左布局的优化处理等。最重要...
3901 0
Winform控件优化之TabControl控件的美化和功能扩展
Winform中Textbox、NumericUpDown等修改高度,禁止输入数字或内容的实现
Winform中的Textbox、NumericUpDown控件通常在单行的情况下,无法直接通过`Height`属性修改高度,但很多时候我们需要调整其高度,使其显示的更加合理,主要介绍三种方法...
3747 0
|
消息中间件 XML 网络协议
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)
📣读完这篇文章里你能收获到 - Nlog输出至文件/RabbitMQ/远程网络Tcp配置文档 - Nlog配置参数详解 - .NET CORE项目接入
6551 0
『NLog』.Net使用NLog使用方式及详细配置(输出至文件/RabbitMQ/远程网络Tcp)