从鼠标移动事件调用绘图事件

4
当鼠标移动到面板2上时,我需要绘制线条。到目前为止,我已经完成了以下操作。
public Form1()
{           
    InitializeComponent();            

}

private void panel2_Paint(object sender, PaintEventArgs e)
{
    if (isDragging)
    {
        letsPaint(sender, e);
    }
}

private void panel2_MouseMove(object sender, MouseEventArgs e)
{
    if (isDragging) 
    {
        mouseMoveX = e.X;
        mouseMoveY = e.Y;                               
        this.Paint += new PaintEventHandler(panel2_Paint);
    }
}

private void letsPaint(object sender, PaintEventArgs e) 
{             
    Pen blackpen = new Pen(Color.Black, 3);
    Graphics g = e.Graphics;
    g.DrawLine(blackpen, mouseClickedX, mouseClickedY, mouseMoveX, mouseMoveY);
    g.Dispose(); 
}

当我移动鼠标时,没有任何反应。我认为在这里的PaintEventHandler()做错了什么。请告诉我如何解决,并且是否有更好的方法。

另外,我认为我的方法会在窗体上绘制线条,但是我需要在panel2上绘制线条。该怎么做?谢谢您提前帮忙。

1个回答

4
你已经使这个无效:
public Form1()
{           
  InitializeComponent();            
  panel2.Paint += new letsPaint;
}

private void panel2_MouseMove(object sender, MouseEventArgs e)
{
  if (isDragging) {
    mouseMoveX = e.X;
    mouseMoveY = e.Y;                               
    panel2.Invalidate();
  }
}

你不需要释放图形对象(因为你没有创建它),但是你需要释放画笔:

private void letsPaint(object sender, PaintEventArgs e) {             
  using (Pen blackpen = new Pen(Color.Black, 3)) {
    e.Graphics.DrawLine(blackpen, 
                        mouseClickedX, mouseClickedY, mouseMoveX, mouseMoveY);
  }
}

这里有一个与位图一起使用的快速方法:

Bitmap bmp;
Point lastPoint;

public Form1() {
  InitializeComponent();
  bmp = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height, 
                   System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

  panel1.MouseDown += panel1_MouseDown;
  panel1.MouseMove += panel1_MouseMove;
  panel1.Paint += panel1_Paint;
}

void panel1_Paint(object sender, PaintEventArgs e) {
  e.Graphics.DrawImage(bmp, Point.Empty);
}

void panel1_MouseMove(object sender, MouseEventArgs e) {
  if (e.Button == MouseButtons.Left) {
    using (Graphics g = Graphics.FromImage(bmp)) {
      g.DrawLine(Pens.Black, lastPoint, e.Location);
    }
    lastPoint = e.Location;
    panel1.Invalidate();
  }
}

void panel1_MouseDown(object sender, MouseEventArgs e) {
  lastPoint = e.Location;
}

这会导致闪烁,因此您需要将面板替换为双缓冲面板。可以使用以下代码实现:

public class PanelEx : Panel {
  public PanelEx() {
    this.DoubleBuffered = true;
  }
}

1
@user1478137 已更新,但实际上您只是在绘制一个点。 您需要将点存储在列表中或在位图中进行绘制,然后在该绘画事件中绘制位图。 - LarsTech
一切都按照我的意愿运作,但问题是在画完一条线后,当我尝试画另一条线时,之前的线条会被删除。但我不想删除之前的线条,我想保留所有已经画出的线条。我该如何做到这一点? - asdfkjasdfjk
@user1478137 这就是我之前评论的重点。你需要存储这些点,然后在绘制事件中循环遍历它们,或者将你的线条绘制到位图中,然后在绘制事件中仅显示图像即可。 - LarsTech
@user1478137 已更新并附上示例。 - LarsTech
1
谢谢兄弟,你救了我的练习! - Combine
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接