2012-11-09 136 views
3

我想在c#中做一個小畫圖程序。到目前爲止,一切工作正常,只有當我將鼠標移動得足夠快時,纔會出現間隙,應該有一條實線。我已經嘗試了一切從雙緩衝到減少mouse_move事件的間隔(我實際上沒有找到任何方法來做到這一點,我認爲這也會對系統上的其他進程不利)^^在c#中繪製空白

你能在這裏指出我正確的方向?我試圖覆蓋面板的繪畫方法,但是當我嘗試這個似乎沒有發生。

下面的代碼:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace Paint 
{ 
    public partial class Form1 : Form 
    { 

     bool paint; 
     SolidBrush color; 
     //size of brush 
     int pinselGröße; 
     List<Point> pointListe; 

     public Form1() 
     { 
      InitializeComponent(); 
      pointListe = new List<Point>(); 
      paint = false; 
      color = new SolidBrush (Color.Black); 
      //get brush size from combobox 
      pinselGröße = Convert.ToInt32 (nudBrushSize.Value); 
     } 

     private void btnExit_Click (object sender, EventArgs e) 
     { 
      this.Close(); 
     } 

     private void btnClear_Click (object sender, EventArgs e) 
     { 
      Graphics gfx = pnlCanvas.CreateGraphics(); 
      gfx.Clear (pnlCanvas.BackColor); 
     } 

     private void pnlCanvas_MouseDown (object sender, MouseEventArgs e) 
     { 
      paint = true; 
      Graphics grfx = pnlCanvas.CreateGraphics(); 
      //draw a rectangle with brush "color" and pinselGröße as the brush size 
      grfx.FillRectangle (color, e.X, e.Y, pinselGröße, pinselGröße); 
     } 

     private void pnlCanvas_MouseMove (object sender, MouseEventArgs e) 
     { 
      if (paint) 
      { 
       //Graphics grfx = pnlCanvas.CreateGraphics(); 
       ////put old position of mouse into variable 
       //int altePosX = e.X; 
       //int altePosY = e.Y; 
       ////grfx.FillEllipse (color, e.X, e.Y, pinselGröße, pinselGröße); 
       //grfx.FillRectangle(color, e.X, e.Y, pinselGröße, pinselGröße); 
       //grfx.Dispose(); 
       pointListe.Add(e.Location); 
       pnlCanvas.Invalidate(); 
      } 
     } 

     private void pnlCanvas_Paint(PaintEventArgs e) 
     { 

      e.Graphics.DrawLines(new Pen(color), pointListe.ToArray()); 
     } 

     private void pnlCanvas_MouseUp (object sender, MouseEventArgs e) 
     { 
      paint = false; 
     } 

     private void nudBrushSize_ValueChanged (object sender, EventArgs e) 

      //when value of combobox changes, read value into brush size variable 
      pinselGröße = Convert.ToInt32 (nudBrushSize.Value); 
     } 

     private void cmbColor_SelectedIndexChanged (object sender, EventArgs e) 
     {    
      int index = cmbColor.SelectedIndex; 
      color.Dispose(); 
      switch (index) 
      { 
       case 0: 
        { 
         color = new SolidBrush (Color.Black); 
         break; 
        } 
       case 1: 
        { 
         Console.WriteLine ("Geht"); 
         color = new SolidBrush (Color.Red); 
         break; 
        } 
       case 2: 
        { 
         color = new SolidBrush (Color.Blue); 
         break; 
        } 
       case 3: 
        { 
         color = new SolidBrush (Color.Green); 
         break; 
        } 
      } 
     } 


    } 
} 

當我做這種方式:

private void pnlCanvas_MouseMove (object sender, MouseEventArgs e) 
     { 
      if (paint) 
      { 
       Graphics grfx = pnlCanvas.CreateGraphics(); 
       ////put old position of mouse into variable 
       int altePosX = e.X; 
       int altePosY = e.Y; 
       //grfx.FillEllipse (color, e.X, e.Y, pinselGröße, pinselGröße); 
       grfx.FillRectangle(color, e.X, e.Y, pinselGröße, pinselGröße); 
       grfx.Dispose(); 
       //pointListe.Add(e.Location); 
       //pnlCanvas.Invalidate(); 
      } 
     } 

     //private void pnlCanvas_Paint(PaintEventArgs e) 
     //{ 
     // Console.Write("mjsda2"); 
     // e.Graphics.DrawLines(new Pen(color), pointListe.ToArray()); 
     //} 

我得到這個:

enter image description here

+0

給予我們不要用英文寫的,你減少量代碼的人會盡力幫助你。 – Snowbear

+0

好的,對不起,我添加了一些理解意見。 – LeonidasFett

回答

4

我不知道我們是在繪圖模式去爲,所以這裏是兩個版本:

另外值得一提,你的Paint事件處理程序有錯誤的簽名,因此可能沒有掛接到pnlCanvas。

在做塗料代碼時,您應該(幾乎)不需要致電CreateGraphics--它通常表示「您做錯了」。

這將讓你通過點擊點畫線:

public partial class Form1 : Form 
{ 

    SolidBrush color; 
    List<Point> pointListe; 
    Point _mousePoint; 

    public Form1() 
    { 
     InitializeComponent(); 
     pointListe = new List<Point>(); 
     color = new SolidBrush(Color.Black); 
    } 

    private void btnClear_Click(object sender, EventArgs e) 
    { 
     pointListe.Clear(); 
     pnlCanvas.Invalidate(); 
    } 

    private void pnlCanvas_MouseDown(object sender, MouseEventArgs e) 
    { 
     pointListe.Add(e.Location); 
    } 

    private void pnlCanvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     _mousePoint = e.Location; 
     pnlCanvas.Invalidate(); 
    } 

    private void pnlCanvas_Paint(object sender, PaintEventArgs e) 
    { 
     if (pointListe.Count > 1) 
     { 
      e.Graphics.DrawLines(new Pen(color), pointListe.ToArray()); 
     } 

     if (pointListe.Any()) 
     { 
      e.Graphics.DrawLine(new Pen(color), pointListe.Last(), _mousePoint); 
     } 
    } 

} 

,這將繪製一個連續的行:

public partial class Form1 : Form 
{ 

    SolidBrush color; 
    List<List<Point>> _lines; 
    Boolean _mouseDown; 

    public Form1() 
    { 
     InitializeComponent(); 
     _lines = new List<List<Point>>(); 
     color = new SolidBrush(Color.Black); 
     _mouseDown = false; 
    } 

    private void btnClear_Click(object sender, EventArgs e) 
    { 
     _lines.Clear(); 
     pnlCanvas.Invalidate(); 
    } 

    private void pnlCanvas_MouseDown(object sender, MouseEventArgs e) 
    { 
     _mouseDown = true; 
     _lines.Add(new List<Point>()); 
    } 

    private void pnlCanvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (_mouseDown) 
     { 
      _lines.Last().Add(e.Location); 
      pnlCanvas.Invalidate(); 
     } 
    } 

    private void pnlCanvas_MouseUp(object sender, MouseEventArgs e) 
    { 
     _mouseDown = false; 
    } 

    private void pnlCanvas_Paint(object sender, PaintEventArgs e) 
    { 
     foreach (var lineSet in _lines) 
     { 
      if (lineSet.Count > 1) 
      { 
       e.Graphics.DrawLines(new Pen(color), lineSet .ToArray()); 
      } 
     } 

    } 

} 
+0

我不知道如果我在這裏丟失了一些東西,但是這也給我也沒有輸出,即使我添加了對象發件人到pnlCanvas_Paint方法的sig。小提示:我只是手動添加了這一個方法,沒有別的(可能需要一個處理程序?)但我不知道這是否有任何意義 – LeonidasFett

+2

+1的詳細答案我可以補充一點,如果他想繼續繪製像素而不是線條,他應該在背部位圖上繪製,然後在畫布上繪製該位圖在Paint事件處理程序中,如果PaintBackground沒有被覆蓋(取決於畫布是什麼),你的代碼也會產生閃爍,所以我建議先在位圖上繪製,然後在畫布上繪製位圖。 –

+1

@ user1589728你需要在你的代碼中設置pnlCanvas.Paint + = new PaintEventHandler(pnlCanvas_Paint); –

2

這不是很清楚,我在那裏的空白正在發生,但不應該在MouseDown事件中添加第一個點?這能解釋你所看到的差距的類型嗎?

爲什麼你在填充MouseDown事件中的矩形?

否則,也許這些間隙看起來像一個截圖。

+0

我認爲他是通過點擊鼠標向下繪畫來支持繪製單個「點」(僅向下和向上拖動)。 – tcarvin

+0

但在其他情況下,是的,它看起來像僞造也記錄列表中的鼠標點將導致一個空白,初始「點」後面是一個小的非繪製區域,然後是從第一個鼠標移動。接得好! – tcarvin

+0

我在MouseMove方法中添加了點,但正如我所說的,當我這樣做時,沒有任何東西被繪製。只有當我刪除重寫方法,而是在MouseMove方法中畫線時,它給了我所說的空白。 – LeonidasFett

2

鼠標移動事件將會跳過 - 鼠標移動的速度可能相當快,速度比事件快,並且您的應用可以跟上。因此,您將無法獲得連續的鼠標移動流,每個像素一個。

你需要做的是跟蹤你在前一個鼠標移動中獲得的前一個位置,然後不是畫一個點,而是畫一條從前一個位置到當前位置的一條線。除非用戶快速瘋狂地移動鼠標,否則這將近似於鼠標的移動,以至於您不會注意到它沒有精確跟蹤每個像素。