2014-02-11 89 views
-1

我想在的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); 

       } 
      } 

     } 
    } 

}

有谁能够告诉我什么,我做错了什么?因为我不知道该怎么办?发生

+0

面板应该双缓冲以避免看到背景被绘制。你会发现一个在[这个答案](http://stackoverflow.com/questions/3113190/double-buffering-when-not-drawing-in-onpaint-why-doesnt-it-work/3113515#3113515),BufferedPanel类。或者使用PictureBox,默认情况下是双缓冲。 –

回答

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 

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

valter

+0

我将尝试第二次,因为双缓冲只会使情况变得更糟= \, 你有没有说明如何做第二个解决方案(简单的例子将是巨大的)和THX回答 – Zlex

+0

@ user3278650我也许有在VB中的东西任何refrence .net如果适合你。 –

+0

是啊,什么都可以帮助.... – Zlex