简体   繁体   English

为什么图形没有绘制到面板上

[英]How come the graphics is not drawing onto the panel

I want to draw a grid in my panel.我想在我的面板中绘制一个网格。 The graphics object (screen) that i created with bitmap isn't drawing in my panel.我用位图创建的图形对象(屏幕)没有在我的面板中绘制。 I tried with debugging to look if the screen wasn't drawing but that wasn't the case.我尝试调试以查看屏幕是否未绘制,但事实并非如此。

I tried creating the graphic object from the panel createGraphic method and the parameter painteventargs from the panel paint method.我尝试从面板painteventargs方法创建图形对象,并从面板绘制方法创建参数painteventargs Both times when I used it to draw it with OnPaint it took too long.两次我用它用OnPaint绘制它都花了太长时间。

public Main()
{
    InitializeComponent();
    backBuffer = new Bitmap(drawPanel.Width, drawPanel.Height);
    screen = Graphics.FromImage(backBuffer);
    sizeGridPoints = 2;
    lenghtBetweenGridPoints = 10;
}

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    screen.Clear(Color.Black);
    DrawGrid();
}

private void DrawGrid()
{
    for(int x = lenghtBetweenGridPoints; x < drawPanel.Width; x += lenghtBetweenGridPoints)
    {
        for(int y = lenghtBetweenGridPoints; y < drawPanel.Height; y+= lenghtBetweenGridPoints)
        {
            screen.FillEllipse(new SolidBrush(Color.Green), x, y, sizeGridPoints, sizeGridPoints);
        }
    }
}

If you create a Graphics object from a bitmap, it will draw on this bitmap, not on your user interface.如果您从位图创建Graphics对象,它将在该位图上绘制,而不是在您的用户界面上。 Instead, use the Graphics object from the PaintEventArgs e of your OnPaint method, to draw directly on the form or a control.相反,使用OnPaint方法的PaintEventArgs e中的Graphics对象,直接在窗体或控件上绘制。

e.Graphics.FillEllipse(new SolidBrush(Color.Green), x, y, sizeGridPoints, sizeGridPoints);

You should never create your own Graphics object.您永远不应该创建自己的Graphics对象。

Create your own grid control:创建您自己的网格控件:

public class GridPanel : Panel
{
    public GridPanel()
    {
        DoubleBuffered = true; // Speeds up drawing, e.g. when panel is resized.

        // Set default colors
        BackColor = Color.Black;
        ForeColor = Color.Green;
    }

    private int _lenghtBetweenGridPoints = 20;
    public int LenghtBetweenGridPoints
    {
        get { return _lenghtBetweenGridPoints; }
        set {
            if (value != _lenghtBetweenGridPoints) {
                _lenghtBetweenGridPoints = value;
                Invalidate(); // Redraw the grid.
            }
        }
    }

    private int _sizeGridPoints = 3;
    public int SizeGridPoints
    {
        get {
            return _sizeGridPoints;
        }
        set {
            if (value != _sizeGridPoints) {
                _sizeGridPoints = value;
                Invalidate(); // Redraw the grid.
            }
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // e.Graphics.Clear(Color.Black); Not necessary. We use the BackColor of the panel.
        if (LenghtBetweenGridPoints > 0 && SizeGridPoints > 0) {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // Optional.
            using (var brush = new SolidBrush(ForeColor)) { // We use the ForeColor of the panel.
                for (int x = LenghtBetweenGridPoints; x < Width; x += LenghtBetweenGridPoints) {
                    for (int y = LenghtBetweenGridPoints; y < Height; y += LenghtBetweenGridPoints) {
                        e.Graphics.FillEllipse(brush, x, y, SizeGridPoints, SizeGridPoints);
                    }
                }
            }
        }
    }
}

Once it has been compiled, it will automatically appear in toolbox window and you can drag and drop it on your form.编译完成后,它将自动出现在工具箱窗口中,您可以将其拖放到表单上。 You will even be able to edit the properties LenghtBetweenGridPoints and SizeGridPoints in the properties window.您甚至可以在属性窗口中编辑属性LenghtBetweenGridPointsSizeGridPoints

You could also simply use the already available BackColor and ForeColor properties of the panel for the grid.您也可以简单地将面板的已经可用的BackColorForeColor属性用于网格。 This would allow you to set the colors in the properties window as well.这也将允许您在属性窗口中设置颜色。 Don't forget to dispose brushes that you have created.不要忘记处理您创建的画笔。


Important: Do not call OnPaint directly.重要提示:不要直接调用OnPaint Instead, call the Invalidate or Refresh methods of the object you want to redraw.相反,调用要重绘的对象的InvalidateRefresh方法。 The point is that Windows decides when to call OnPaint .关键是 Windows 决定何时调用OnPaint Eg if Invalidate is called too frequently (eg 5 times in 1/60 seconds), Windows might decide to not call OnPaint every time, as this would create lag.例如,如果Invalidate调用过于频繁(例如 1/60 秒内调用 5 次),Windows 可能决定不每次都调用OnPaint ,因为这会造成延迟。 On the other hand, when the user resizes the panel, Windows will call OnPaint automatically.另一方面,当用户调整面板大小时,Windows 会自动调用OnPaint If you restore a window that was minimized, this will re-paint the control as well.如果您恢复最小化的窗口,这也将重新绘制控件。 Otherwise it would remain black.否则它会一直是黑色的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM