在c#winforms中使用paint方法时如何防止闪烁?

时间:2021-12-01 20:56:06

Code:

码:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawRectangle(Pens.White,
    e.ClipRectangle.Left,
    e.ClipRectangle.Top,
    e.ClipRectangle.Width - 1,
    e.ClipRectangle.Height - 1);
    base.OnPaint(e);
}

How to avoid flickering. Above is the panel1_Paint method for Paint event in Panel. Thanks.

如何避免闪烁。以上是Panel中Paint事件的panel1_Paint方法。谢谢。

3 个解决方案

#1


3  

Some of the Windows Forms controls don't have double buffering enabled by default. I'm not sure if the panel is one of them, but it can't hurt to try enabling it.

默认情况下,某些Windows窗体控件没有启用双缓冲。我不确定该面板是否是其中之一,但尝试启用它不会有什么坏处。

Unfortunately Control.DoubleBuffered is a protected, so unless you inherit from the control you have to resort to reflection to enable it.

不幸的是,Control.DoubleBuffered是受保护的,因此除非您从控件继承,否则必须使用反射来启用它。

Control ctrl;
ctrl.GetType()
    .GetProperty("DoubleBuffered", 
                 BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(control, true, null);

#2


0  

The problem is most likely caused by not having double buffering enabled. Double buffering is the process of first writing to an internal (invisible) buffer until all draw operations are completed and then blitting said buffer to the visible buffer, this avoids flickering by simplifying the draw operation on the actual buffer.

问题很可能是由于没有启用双缓冲。双缓冲是首先写入内部(不可见)缓冲区直到所有绘制操作完成然后将所述缓冲区blit到可见缓冲区的过程,这通过简化实际缓冲区上的绘制操作来避免闪烁。

http://msdn.microsoft.com/en-us/library/3t7htc9c(v=vs.110).aspx lists possible solutions to it. Setting the property DoubleBuffered to true appears to be the easiest way to do such. However, since it is protected you either need to use reflection to access it or inherit from the panel class, set it to true in your new class and use said new class:

http://msdn.microsoft.com/en-us/library/3t7htc9c(v=vs.110).aspx列出了可能的解决方案。将属性DoubleBuffered设置为true似乎是最简单的方法。但是,由于它受到保护,您需要使用反射来访问它或从面板类继承,在新类中将其设置为true并使用所述新类:

public class myPanel : Panel {
    public myPanel() : base() {
        this.DoubleBuffered = true;
    }
}

#3


0  

There are a few ways to prevent flickering for container controls, such as the panel control. Each of these methods involves deriving from the Panel base class (or other suitable base class).

有几种方法可以防止容器控件的闪烁,例如面板控件。这些方法中的每一个都涉及从Panel基类(或其他合适的基类)派生。

The first method is enabling double buffering, which can be accomplished using the following line of code:

第一种方法是启用双缓冲,可以使用以下代码行完成:

this.DoubleBuffered = true;

The second effective method is overriding the CreateParams property and enabling WS_EX_COMPOSITED. This is done using the following code:

第二种有效方法是重写CreateParams属性并启用WS_EX_COMPOSITED。这是使用以下代码完成的:

private const int WS_EX_COMPOSITED = 0x02000000;

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

In order to access either of these properties, as we have determined we need to derive from the base class. Therefore the entire class declaration might look something like this:

为了访问这些属性中的任何一个,我们已经确定需要从基类派生。因此,整个类声明可能如下所示:

public class GraphicsPanel : Panel
{
    private const int WS_EX_COMPOSITED = 0x02000000;

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

    public GraphicsPanel()
    {
        this.DoubleBuffered = true;
    }
}

Upon rebuilding our solution, a new control will be added to the toolbox called GraphicsPanel, which we can visually design. At run-time, you should notice substantially less flickering.

在重建我们的解决方案后,将在名为GraphicsPanel的工具箱中添加一个新控件,我们可以直观地设计它。在运行时,您应该注意到闪烁明显减少。

#1


3  

Some of the Windows Forms controls don't have double buffering enabled by default. I'm not sure if the panel is one of them, but it can't hurt to try enabling it.

默认情况下,某些Windows窗体控件没有启用双缓冲。我不确定该面板是否是其中之一,但尝试启用它不会有什么坏处。

Unfortunately Control.DoubleBuffered is a protected, so unless you inherit from the control you have to resort to reflection to enable it.

不幸的是,Control.DoubleBuffered是受保护的,因此除非您从控件继承,否则必须使用反射来启用它。

Control ctrl;
ctrl.GetType()
    .GetProperty("DoubleBuffered", 
                 BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(control, true, null);

#2


0  

The problem is most likely caused by not having double buffering enabled. Double buffering is the process of first writing to an internal (invisible) buffer until all draw operations are completed and then blitting said buffer to the visible buffer, this avoids flickering by simplifying the draw operation on the actual buffer.

问题很可能是由于没有启用双缓冲。双缓冲是首先写入内部(不可见)缓冲区直到所有绘制操作完成然后将所述缓冲区blit到可见缓冲区的过程,这通过简化实际缓冲区上的绘制操作来避免闪烁。

http://msdn.microsoft.com/en-us/library/3t7htc9c(v=vs.110).aspx lists possible solutions to it. Setting the property DoubleBuffered to true appears to be the easiest way to do such. However, since it is protected you either need to use reflection to access it or inherit from the panel class, set it to true in your new class and use said new class:

http://msdn.microsoft.com/en-us/library/3t7htc9c(v=vs.110).aspx列出了可能的解决方案。将属性DoubleBuffered设置为true似乎是最简单的方法。但是,由于它受到保护,您需要使用反射来访问它或从面板类继承,在新类中将其设置为true并使用所述新类:

public class myPanel : Panel {
    public myPanel() : base() {
        this.DoubleBuffered = true;
    }
}

#3


0  

There are a few ways to prevent flickering for container controls, such as the panel control. Each of these methods involves deriving from the Panel base class (or other suitable base class).

有几种方法可以防止容器控件的闪烁,例如面板控件。这些方法中的每一个都涉及从Panel基类(或其他合适的基类)派生。

The first method is enabling double buffering, which can be accomplished using the following line of code:

第一种方法是启用双缓冲,可以使用以下代码行完成:

this.DoubleBuffered = true;

The second effective method is overriding the CreateParams property and enabling WS_EX_COMPOSITED. This is done using the following code:

第二种有效方法是重写CreateParams属性并启用WS_EX_COMPOSITED。这是使用以下代码完成的:

private const int WS_EX_COMPOSITED = 0x02000000;

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

In order to access either of these properties, as we have determined we need to derive from the base class. Therefore the entire class declaration might look something like this:

为了访问这些属性中的任何一个,我们已经确定需要从基类派生。因此,整个类声明可能如下所示:

public class GraphicsPanel : Panel
{
    private const int WS_EX_COMPOSITED = 0x02000000;

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

    public GraphicsPanel()
    {
        this.DoubleBuffered = true;
    }
}

Upon rebuilding our solution, a new control will be added to the toolbox called GraphicsPanel, which we can visually design. At run-time, you should notice substantially less flickering.

在重建我们的解决方案后,将在名为GraphicsPanel的工具箱中添加一个新控件,我们可以直观地设计它。在运行时,您应该注意到闪烁明显减少。