23

我有一个面板,上面有一个轮盘,我需要对面板进行双重缓冲,使其停止闪烁。谁能帮我吗?

编辑:

是的,我已经尝试过了。

panel1.doublebuffered 不存在,只有 this.doublebuffered。而且我不需要缓冲表单,只需缓冲面板。

4

6 回答 6

25

您需要从 Panel 或 PictureBox 派生。

这取决于您选择启用缓冲的方式。

如果你设置了 this.DoubleBuffer 标志,那么你应该没问题。

如果您手动更新样式,那么您必须自己在 WM_PAINT 中绘制表单。

如果您真的有野心,您可以维护并绘制自己的后台缓冲区作为位图。


using System.Windows.Forms;

public class MyDisplay : Panel
{
    public MyDisplay()
    {
        this.DoubleBuffered = true;

        // or

        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        UpdateStyles();
    }
}
于 2009-05-04T00:57:43.333 回答
21

另一种方法是调用双缓冲成员,使用 InvokeMember 方法:

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

通过这种方式,您不必创建子类

于 2015-07-22T12:17:07.057 回答
5

您可以将DoubleBuffered-Property 在派生类中公开Panel

public class DoubleBufferedPanel : Panel
{        
    [DefaultValue(true)]
    public new bool DoubleBuffered
    {
        get
        {
            return base.DoubleBuffered;
        }
        set
        {
            base.DoubleBuffered = value;
        }
    }
}
于 2013-11-10T20:00:42.917 回答
4

Winform面板有一个DoubleBuffered 属性

编辑:我应该注意到它受到保护。其他人已经描述了如何对其进行子类化。:)

于 2009-05-04T00:37:36.580 回答
1

只是扩展 User79775 的答案,如果您想在 VB.net 中实现这一点,请这样做:

Imports System.Windows.Forms

Public Class MyDisplay
    Inherits Panel

    Public Sub New()
        Me.DoubleBuffered = True

        ' or

        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        UpdateStyles()
    End Sub
End Class
于 2019-03-15T18:17:24.000 回答
0

我和你一样的困境。我在 C# WinForm 中放置了一个面板,并将其用作几何动画的显示区域。由计时器触发的多次重绘操作,再加上偶尔调整窗口大小,都导致该面板严重闪烁。这里提供的其他解决方案似乎都依赖于激活DoubleBuffered标志,但这对我的体验没有任何影响。

正确的方法是使用System.Drawing.BufferedGraphics该类并在您的应用程序中利用它。

这是它的概述,以及一个实际有效的示例(不再闪烁!)。

这个例子有点矫枉过正,因为它突出了至少两种在翻转图形缓冲区之前执行渲染的方法;您只需要在实施中保留您喜欢的那个。

我个人选择将 Panel 子类化为一个新DoubleBufferedPanel类。我只是使用基本面板的Paint()方法和调用Refresh()来翻转缓冲区。

于 2021-12-03T21:04:00.017 回答