2012-11-09 67 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

鼠标移动事件将会跳过 - 鼠标移动的速度可能相当快,速度比事件快,并且您的应用可以跟上。因此,您将无法获得连续的鼠标移动流,每个像素一个。

你需要做的是跟踪你在前一个鼠标移动中获得的前一个位置,然后不是画一个点,而是画一条从前一个位置到当前位置的一条线。除非用户快速疯狂地移动鼠标,否则这将近似于鼠标的移动,以至于您不会注意到它没有精确跟踪每个像素。