2014-02-11 112 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