2

今天,当我在上面画画时,我正在尝试用闪烁的面板解决问题。

我读了很多线程,比如:

因此,我尝试使用 doubleBuffered 在 PictureBox、MyPanel 上绘图,但是当我阅读时,我发现我不能每次都使用 g.Clear() 的最佳解决方案,此后,即使在非 doubleBuffered 面板上,闪烁也消失了。

我什至读到,我应该在绘制完成后释放图形。所以我到处使用(Graphics g = panel.CreateGraphics())。

所以我的问题是,仅当我在位图上绘制一些东西时才为位图创建图形是个好主意吗?因为在我创建 Bitmap 和 Graphics 之前(仅针对此位图,并非针对所有组件),所以我每次都有可用于此位图的 Graphics

这是我的代码:

public void newSizeDrawing()
    {
        Size size = collector.getLetterSize(selectedName);
        Size drawingSize = new Size(size.Width * (pixelSizeArray[pixelSize] + 1),size.Height * (pixelSizeArray[pixelSize] + 1));
        bitmapDraw = new Bitmap(drawingSize.Width, drawingSize.Height);
        int width = (this.MinimumSize.Width - panelDraw.MinimumSize.Width) + drawingSize.Width + 10;
        int height = (this.MinimumSize.Height - panelDraw.MinimumSize.Height) + drawingSize.Height + 10;
        this.Size = new Size(
            (width > this.MinimumSize.Width) ? width : this.MinimumSize.Width,
            (height > this.MinimumSize.Height) ? height : this.MinimumSize.Height);
        zeroDrawPosition = new Point((panelDraw.Size.Width - bitmapDraw.Width) / 2 - 1, (panelDraw.Size.Height - bitmapDraw.Height) / 2 - 1);
        using (Graphics g = panelDraw.CreateGraphics())
        {
            g.Clear(panelDraw.BackColor);
        }
        redrawDrawingLetter();
    }
public void redrawDrawingLetter()
    {
        bool[][] grid = collector.getArray(selectedName);
        using (Graphics graphicDraw = Graphics.FromImage(bitmapDraw))
        {
            graphicDraw.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
            graphicDraw.Clear(panelDraw.BackColor);
            int pxSize = pixelSizeArray[pixelSize];
            for (int y = 0; y < grid.Length; y++)
            {
                for (int x = 0; x < grid[y].Length; x++)
                {
                    graphicDraw.FillRectangle((grid[y][x] ? Brushes.Black : Brushes.White), x * (pxSize + 1), y * (pxSize + 1), pxSize, pxSize);
                }
            }
        }
        redrawDrawingPanel();
    }
private void redrawDrawingPanel()
    {
        using (Graphics g = panelDraw.CreateGraphics())
        {
            if (bitmapDraw != null)
                g.DrawImage(bitmapDraw, zeroDrawPosition);
        }
    }
private void panelDraw_Paint(object sender, PaintEventArgs e)
    {
        redrawDrawingPanel();
    }

没有人能向我解释如何用 C# 画出最好的画法。所以也许我的代码不好,但这就是我问如何正确执行它的原因。

newSizeDrawing仅由我自己调用,当用户单击+-按钮时。如果像素打开或关闭,我有 bool 二维数组。这是用于为微芯片和 LED 显示屏绘制字母的程序(通常是 8px 的字母高度)。

我写了一个方法来检查鼠标是否从一个“像素”移动到另一个,所以我不会在每次调用 mouseMove 事件后重新绘制它,因为“像素”可以从 10x10 像素到 30x30 像素。

4

1 回答 1

1
private void panelDraw_Paint(object sender, PaintEventArgs e)
{
    redrawDrawingPanel();
}

这是根本错误的。Paint 事件通过 e.Graphics 让您绘制您想要绘制的任何内容。当您打开双缓冲时,e.Graphics 引用位图,它使用 BackColor 进行初始化。然后,您继续使用从 CreateGraphics() 获得的另一个Graphics 对象进行绘图。那个直接画到屏幕上。

您看到的闪烁效果非常明显。一瞬间,您会看到其他 Graphics 上下文绘制的内容。然后您的 panelDraw_Paint() 方法返回并且 Winforms 绘制双缓冲位图。它上面什么都没有,所以它会立即删除你画的东西。

修改 redrawDrawingPanel() 方法并给它一个 Graphics 类型的参数。在调用中传递 e.Graphics。并且只使用该图形对象,删除对 CreateGraphics() 的所有调用。

于 2012-07-10T00:14:53.170 回答