形式是闪烁,而我重绘和绘制形状Winforms

时间:2014-02-11 23:05:52

标签: c# winforms

我尝试用winforms绘制带有鼠标事件的椭圆,
鼠标停机时,向上移动 我的代码是这样的:

    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

    }
}

我的主要问题是,当我在列表中保存圆圈或rectinagle时,每次我绘制一个新的圆圈/ rectiangle时,列表中的形状闪烁...... 这是我的Onpaint活动:

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);

                }
            }

        }
    }

}

谁能告诉我我做错了什么?因为我不知道该怎么办?

1 个答案:

答案 0 :(得分:0)

闪烁发生的原因是每个涂料中都有擦除背景。尝试两种解决方案

首先
Use double buffer

第二(更难)
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

使用代码编辑

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

此示例绘制省略号。绘制任何其他形状也很容易。

瓦尔特