双缓冲在面板上无法工作?

3

我正在开发一个类似于MS Paint的小型绘画程序。目前,我正在尝试实现'选择功能'. 但我面临屏幕闪烁问题,所以我进行了一些研究,并发现我应该创建自己的Panel类。

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

            this.SetStyle(ControlStyles.UserPaint |
              ControlStyles.AllPaintingInWmPaint |
              ControlStyles.ResizeRedraw |
              ControlStyles.ContainerControl |
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.SupportsTransparentBackColor
              , true);

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.UpdateStyles();
        }
    }

在主表单中,有以下字段:
MyDisplay panel1 = new MyDisplay();
Graphics graphics1 = panel1.CreateGraphics();

我在一个面板上使用了3个事件:
  1. MouseDown - 在这里我得到了点p1
  2. MouseMove - 这就是我遇到闪烁问题的地方,我每次点击鼠标移动时都会调用graphics1.drawRectangle(...)graphics1.Clear()
  3. MouseUp - 我只是最后一次绘制矩形。
为什么会出现问题呢?即使整个面板都是白色的,并且只有一个矩形,我仍然面临着闪烁问题。谢谢。
编辑:
我已经覆盖了OnPaint方法,但我仍然不知道下一步该怎么做。
   protected override void OnPaint(PaintEventArgs e)
    {
        // Call the OnPaint method of the base class.
        base.OnPaint(e);
        // Call methods of the System.Drawing.Graphics object.
        e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle);
    } 

编辑2: 我应该在位图/图像上绘制并覆盖OnPaint方法,从那里复制图像并将其粘贴到面板上吗?


1
你正在使用CreateGraphics()破坏双缓冲特性。你必须重写OnPaint()方法来进行绘制并避免闪烁。 - Hans Passant
你介意给我一些关于使用OnPaint的提示吗?我完全不知道它应该如何工作,我一直在尝试在谷歌上查找,但没有结果。 - Patryk
1个回答

1

删除定义graphics1字段的行。

在OnPaint重写中执行所有绘画操作,使用传递给PaintEventArgs对象的Graphics对象。使用Invalidate()、Refresh()和Update()方法来控制来自其他代码的重新绘制的时间。

如果遇到任何特定困难,请回调。


你能给我一些例子吗?我不确定它应该是什么样子的。如果我想画矩形和圆形,我应该在OnPaint中放置这两个方法吗? - Patryk
我应该在位图/图像上绘制,然后覆盖OnPaint方法以从那里复制图像并将其粘贴到面板上吗? - Patryk
在位于OnPaint方法中通常会同时进行从位图绘制和将位图绘制到屏幕上的操作。 - Pieter Geerkens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接