使用双缓冲技术解决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);

相关文章
|
算法 Windows
Winform控件优化之实现无锯齿的圆角窗体(或任意图形的无锯齿丝滑的窗体或控件)【借助LayeredWindow】
在一般能搜到的所有实现圆角窗体的示例中,都有着惨不忍睹的锯齿...而借助于Layered Windows,是可以实现丝滑无锯齿效果的Form窗体的,其具体原理就是分层窗体....
1983 0
Winform控件优化之实现无锯齿的圆角窗体(或任意图形的无锯齿丝滑的窗体或控件)【借助LayeredWindow】
|
算法 API C#
Winform控件优化之圆角按钮【各种实现中的推荐做法】(下)
最终优化实现ButtonPro按钮(继承自Button),既提供Button原生功能,又提供扩展功能,除了圆角以外,还实现了圆形、圆角矩形的脚尖效果、边框大小和颜色、背景渐变颜色...
2720 0
Winform控件优化之圆角按钮【各种实现中的推荐做法】(下)
WPF控件和窗体一起放大一起缩小
WPF控件和窗体一起放大一起缩小
307 0
|
JSON 小程序 JavaScript
小程序触底加载与下拉刷新功能的设计与实现
在最近做小程序的时候有这么一个很常见的需求,加载一个信息列表,要求需要触底加载和下拉刷新,我突然想起来掘金小册界面和这个需求很相似,接下来我给大家介绍一下我的实现方案。
433 0
小程序触底加载与下拉刷新功能的设计与实现
|
C# 图形学 Windows
Winform控件优化之圆角按钮【各种实现中的推荐做法】(上)
Windows 11下所有控件已经默认采用圆角,其效果更好、相对有着更好的优化...尝试介绍很常见的圆角效果,通过重写控件的OnPaint方法实现绘制,并在后面进一步探索对应的优化和可能的问题
1751 0
Winform控件优化之圆角按钮【各种实现中的推荐做法】(上)
|
大数据 C#
利用WPF的ListView进行大数据量异步加载
原文:利用WPF的ListView进行大数据量异步加载      由于之前利用Winform的ListView进行大数据量加载的时候,诟病良多,所以今天试着用WPF的ListView来做了一下,结果没有让我失望,我将一个拥有43000行,510列的csv文件导入到了ListView中,总共耗时在10s左右,并且在导入的过程中,软件界面上的提示信息一直在提示当前导入了多少条。
1780 0
|
C# Windows
wpf 判断鼠标在一段时间内是否移动
原文:wpf 判断鼠标在一段时间内是否移动 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/config_man/article/details/7484257 ...
1190 0
|
C#
WPF中窗口控件的跨线程调用
原文:WPF中窗口控件的跨线程调用 在WinForm中,我们要跨线程访问窗口控件,只需要设置属性CheckForIllegalCrossThreadCalls = false;即可。 在WPF中要麻烦一下,同样的不允许跨线程访问,因为没有权限,访问了会抛异常; 没有CheckForIllegalCrossThreadCalls 属性,怎么办? 在WPF中的窗口控件都有一个Dispatcher属性,允许访问控件的线程;既然不允许直接访问,就告诉控件我们要干什么就好了。
2026 0
|
C#
解决WPF的ScrollViewer在使用触摸屏时,滑到尽头窗口抖动的情况
原文:解决WPF的ScrollViewer在使用触摸屏时,滑到尽头窗口抖动的情况 wpf的ScrollViewer在触摸条件下 默认在尽头时会有一个窗口一起被拖动的FeedBack,但对用户的交互很不友好,尤其是全屏应用,一划就看到了后面的桌面。
1496 0