-1

i trying in winforms to draw an ellipse with mouse event ,
when mouse is down ,move and up my code goes like this :

    void panel1_MouseDown(object sender, MouseEventArgs e)
{
    startpoint.X = e.X;
    startpoint.Y = e.Y;

    if (m_drawrectiangle == true)
    {
        m_shape = new Rectiangle(0, 0, this);
        m_shape.Xpos = e.X;
        m_shape.Ypos = e.Y;
        draw = true;
    }
        if (m_draweliipse == true)
        {
            m_shape = new Circle(0, 0, this);
            m_shape.Xpos = e.X;
            m_shape.Ypos = e.Y;
            draw = true;

        }

}
void panel1_MouseUp(object sender, MouseEventArgs e)
{

    if (m_shape != null)
    {
        if(m_shape.Area()==0)
        {
            this.Cursor = Cursors.Default;
            draw = false;
        }
        if (draw == true)
        {
            shapes.Add(m_shape);
            this.Cursor = Cursors.Default;
            draw = false;
            Invalidate();
        }
    }
}
void panel1_MouseMove(object sender, MouseEventArgs e)
{

    this.Text = "(" + e.X + ", " + e.Y + ")";

    if (draw==true  && m_drawrectiangle==true )
    {
        int x = (e.X < 0) ? 0 : e.X;
        int y = (e.Y < 0) ? 0 : e.Y;

        //switch places
        m_shape.Xpos = (x < startpoint.X) ? x : startpoint.X;
        m_shape.Ypos = (y < startpoint.Y) ? y : startpoint.Y;

       ( (Rectiangle)m_shape).Width = Math.Abs(x - startpoint.X);
      ( (Rectiangle) m_shape).Height = Math.Abs(y - startpoint.Y);


        Invalidate(); //re-paint
    }
    if ( draw==true && m_draweliipse==true )
    {
        int x = (e.X < 0) ? 0 : e.X;
        int y = (e.Y < 0) ? 0 : e.Y;

        //switch places
        m_shape.Xpos = (x < startpoint.X) ? x : startpoint.X;
        m_shape.Ypos = (y < startpoint.Y) ? y : startpoint.Y;
    double deltax=Math.Pow(x-startpoint.X,2);
    double deltay=Math.Pow(y-startpoint.Y,2);
    ((Circle)m_shape).Diam =(decimal)Math.Sqrt(deltax +deltay);//typecast safe
        Invalidate(); //re-paint

    }
}

my main problem is that when i save the circle or rectinagle in the list, everytime i drawing a new circle/rectiangle ,the shape in the list Flickering... here my Onpaint event:

protected override void OnPaint(PaintEventArgs e)
{

    if(draw==true)
    {
        m_shape.draw();
    }
    if (shapes.Count > 0)
    {
        foreach (shape a in shapes)
        {
            a.draw();
            if (m_drawarea == true)
            {
                string text1 = a.Area().ToString("0. 00");
                Font font1 = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Point);
                using (Graphics rectangledraw = CreateGraphics())
                {
                    rectangledraw.DrawString(text1, font1, Brushes.Blue, (float)a.Xpos, (float)a.Ypos);

                }
            }

        }
    }

}

can anybody tell me what i am doing wrong ? because i have no idea what to do?

Zlex
  • 147
  • 2
  • 11
  • The panel should be double-buffered to avoid seeing the background being drawn. You find one in [this answer](http://stackoverflow.com/questions/3113190/double-buffering-when-not-drawing-in-onpaint-why-doesnt-it-work/3113515#3113515), BufferedPanel class. Or use a PictureBox instead, it is double-buffered by default. – Hans Passant Feb 12 '14 at 00:23

1 Answers1

0

The flicker occurs because in every paint there is an erase background too. Try two solutions.

First
Use double buffer

Second (Harder)
Create two bitmaps with the size and color of the panel eg bmp1, bmp2
override OnPaintBackground and do nothing.
In your OnPaint:
draw bmp2 to bmp1
draw your shapes to bmp1
draw bmp1 to panel

Edit with code

Private bitmap_monimo As Bitmap
Private bitmap_temporary As Bitmap
Private objGraphics As Graphics

Private mouse_down As Point
Private my_pen As Pen


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    my_pen = New Pen(Color.Black, 1)
    bitmap_monimo = New Bitmap(Panel1.ClientRectangle.Width, Panel1.ClientRectangle.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)
    bitmap_temporary = New Bitmap(Panel1.ClientRectangle.Width, Panel1.ClientRectangle.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)

    Call InitializeSurface()

End Sub

Private Sub InitializeSurface()
    objGraphics = Graphics.FromImage(bitmap_monimo)
    objGraphics.Clear(Panel1.BackColor)
    objGraphics.Dispose()

    objGraphics = Graphics.FromImage(bitmap_temporary)
    objGraphics.Clear(Panel1.BackColor)
    objGraphics.Dispose()
End Sub

Private Sub Panel1_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove
    If e.Button = MouseButtons.Left Then
        bitmap_temporary = bitmap_monimo.Clone()
        objGraphics = Graphics.FromImage(bitmap_temporary)
        objGraphics.DrawEllipse(my_pen, mouse_down.X, mouse_down.Y, e.X - mouse_down.X, e.Y - mouse_down.Y)
        objGraphics.Dispose()

        objGraphics = Panel1.CreateGraphics
        objGraphics.DrawImage(bitmap_temporary, 0, 0, Panel1.Width, Panel1.Height)
        objGraphics.Dispose()
    End If
End Sub

Private Sub Panel1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown
    mouse_down.X = e.X
    mouse_down.Y = e.Y
End Sub

Private Sub Panel1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    e.Graphics.DrawImage(bitmap_temporary, 0, 0, Panel1.Width, Panel1.Height)
End Sub

Private Sub Panel1_MouseUp(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp
    objGraphics = Graphics.FromImage(bitmap_monimo)

    objGraphics.DrawImage(bitmap_temporary, 0, 0, Panel1.Width, Panel1.Height)

    objGraphics.Dispose()
End Sub

This example draws ellipses. It is very easy to draw any other shape as well.

valter