如何在滚动时消除Windows.Forms自定义控件中的闪烁?

时间:2021-11-17 15:53:32

I want to create a custom control in C#. But every time I have to fully redraw my control, it flickers, even if I use double buffering (drawing to an Image first, and blitting that).

我想在C#中创建一个自定义控件。但是每当我必须完全重绘我的控制时,它就会闪烁,即使我使用双缓冲(首先绘制到图像,然后进行blitting)。

How do I eliminate flicker when I have to fully redraw?

当我必须完全重绘时,如何消除闪烁?

4 个解决方案

#1


13  

You could try putting the following in your constructor after the InitiliseComponent call.

您可以尝试在InitiliseComponent调用之后将以下内容放入构造函数中。

SetStyle(ControlStyles.OptimizedDoubleBuffer | 
         ControlStyles.UserPaint |
         ControlStyles.AllPaintingInWmPaint, true);

EDIT:

If you're giving this a go, if you can, remove your own double buffering code and just have the control draw itself in response to the appropriate virtual methods being called.

如果你这样做,你可以删除你自己的双缓冲代码,然后让控件绘制自己以响应被调用的相应虚拟方法。

#2


8  

I pulled this from a working C# program. Other posters have syntax errors and clearly copied from C++ instead of C#

我从一个正在运行的C#程序中提取了这个。其他海报有语法错误,并清楚地从C ++而不是C#复制

SetStyle(ControlStyles.OptimizedDoubleBuffer | 
                        ControlStyles.UserPaint |
                        ControlStyles.AllPaintingInWmPaint, true);

#3


1  

It may be good enough to just call

打电话可能已经足够了

SetStyle(ControlStyles::UserPaint | ControlStyles::AllDrawingInWmPaint, true);

The flickering you are seeing most likely because Windows draws the background of the control first (via WM_ERASEBKGND), then asks your control to do whatever drawing you need to do (via WM_PAINT). By disabling the background paint and doing all painting in your OnPaint override can eliminate the problem in 99% of the cases without the need to use all the memory needed for double buffering.

您最常看到的闪烁是因为Windows首先绘制控件的背景(通过WM_ERASEBKGND),然后要求您的控件执行您需要执行的任何绘制(通过WM_PAINT)。通过禁用背景绘制并在OnPaint覆盖中进行所有绘制可以消除99%的情况下的问题,而无需使用双缓冲所需的所有内存。

#4


0  

You say you've tried double buffering, but then you say drawing to an Image first and blitting that. Have you tried setting DoubleBuffered = true in the constructor rather than doing it yourself with an Image?

你说你已经尝试过双重缓冲,但是你说你先画一张图像然后瞎了。您是否尝试在构造函数中设置DoubleBuffered = true而不是使用Image自己设置?

#1


13  

You could try putting the following in your constructor after the InitiliseComponent call.

您可以尝试在InitiliseComponent调用之后将以下内容放入构造函数中。

SetStyle(ControlStyles.OptimizedDoubleBuffer | 
         ControlStyles.UserPaint |
         ControlStyles.AllPaintingInWmPaint, true);

EDIT:

If you're giving this a go, if you can, remove your own double buffering code and just have the control draw itself in response to the appropriate virtual methods being called.

如果你这样做,你可以删除你自己的双缓冲代码,然后让控件绘制自己以响应被调用的相应虚拟方法。

#2


8  

I pulled this from a working C# program. Other posters have syntax errors and clearly copied from C++ instead of C#

我从一个正在运行的C#程序中提取了这个。其他海报有语法错误,并清楚地从C ++而不是C#复制

SetStyle(ControlStyles.OptimizedDoubleBuffer | 
                        ControlStyles.UserPaint |
                        ControlStyles.AllPaintingInWmPaint, true);

#3


1  

It may be good enough to just call

打电话可能已经足够了

SetStyle(ControlStyles::UserPaint | ControlStyles::AllDrawingInWmPaint, true);

The flickering you are seeing most likely because Windows draws the background of the control first (via WM_ERASEBKGND), then asks your control to do whatever drawing you need to do (via WM_PAINT). By disabling the background paint and doing all painting in your OnPaint override can eliminate the problem in 99% of the cases without the need to use all the memory needed for double buffering.

您最常看到的闪烁是因为Windows首先绘制控件的背景(通过WM_ERASEBKGND),然后要求您的控件执行您需要执行的任何绘制(通过WM_PAINT)。通过禁用背景绘制并在OnPaint覆盖中进行所有绘制可以消除99%的情况下的问题,而无需使用双缓冲所需的所有内存。

#4


0  

You say you've tried double buffering, but then you say drawing to an Image first and blitting that. Have you tried setting DoubleBuffered = true in the constructor rather than doing it yourself with an Image?

你说你已经尝试过双重缓冲,但是你说你先画一张图像然后瞎了。您是否尝试在构造函数中设置DoubleBuffered = true而不是使用Image自己设置?