论图像绘图保存

时间:2011-04-27 11:29:44

标签: c# .net winforms graphics drawing

我在C#中创建了一个小应用程序,我在移动鼠标时绘制一个矩形。

但是,当窗体最小化或最大化时,绘图将被删除。此外,当我第二次绘制时,第一个矩形的绘制将被删除。

我该如何解决这个问题?这是我目前的代码:

   int X, Y;
    Graphics G;
    Rectangle Rec;
    int UpX, UpY, DwX, DwY;


    public Form1()
    {
        InitializeComponent();
        //G = panel1.CreateGraphics();
        //Rec = new Rectangle(X, Y, panel1.Width, panel1.Height);
    }


    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        UpX = e.X;
        UpY = e.Y;
        //Rec = new Rectangle(e.X, e.Y, 0, 0);
        //this.Invalidate();
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        DwX = e.X;
        DwY = e.Y;

        Rec = new Rectangle(UpX, UpY, DwX - UpX, DwY - UpY);
        Graphics G = pictureBox1.CreateGraphics();
        using (Pen pen = new Pen(Color.Red, 2))
        {
            G.DrawRectangle(pen, Rec);
        }
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {            
        if (e.Button == MouseButtons.Left)
        {
            // Draws the rectangle as the mouse moves
            Rec = new Rectangle(UpX, UpY, e.X - UpX, e.Y - UpY);
            Graphics G = pictureBox1.CreateGraphics();

            using (Pen pen = new Pen(Color.Red, 2))
            {
                G.DrawRectangle(pen, Rec);
            }
            G.Save();
            pictureBox1.SuspendLayout();
            pictureBox1.Invalidate();

        }

    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        pictureBox1.Update();            
    }

1 个答案:

答案 0 :(得分:2)

您的图形被删除的原因是因为您正在绘制通过调用Graphics方法获得的CreateGraphics对象。特别是,这行代码不正确:

 Graphics G = pictureBox1.CreateGraphics();

正如您所发现的那样,只要表单重新绘制(当它被最大化,最小化,被屏幕上的另一个对象覆盖或在许多其他可能的情况下发生时),一切都会发生您已经陷入临时Graphics对象的行为已丢失。形式完全重绘自己的内部绘画逻辑;它完全忘记了你暂时吸引它的东西。

在WinForms中绘制持久图像的正确方法是覆盖要绘制的控件的OnPaint method(或者,您也可以处理Paint event )。因此,如果您想在表单上绘画,则可以将绘图代码放入以下方法中:

protected override void OnPaint(PaintEventArgs e)
{
    // Call the base class first
    base.OnPaint(e);

    // Then insert your custom drawing code
    Rec = new Rectangle(UpX, UpY, DwX - UpX, DwY - UpY);
    using (Pen pen = new Pen(Color.Red, 2))
    {
        e.Graphics.DrawRectangle(pen, Rec);
    }
}

要触发重新绘制,只需在任何鼠标事件(MouseDownMouseMoveMouseUp)中调用Invalidate method

this.Invalidate();

但请注意,绝对没有理由在Paint事件处理程序中调用Update method。调用Update方法的所有操作都会强制控件重绘自身。但是当Paint事件被提升时,这已经发生了!