C# 鼠标绘图

5
我希望用鼠标通过e.Xe.Y绘图。我知道应该使用list<Point>,但不知道如何做到这一点。不幸的是,我在drawlines上遇到了问题,无法完成操作。
有人告诉我应该使用drawlines而不是Fillellipse
这是我当前绘制的图片和我想要绘制的图片: drawing http://img.fileup.cz/?di=1413056646794 以下是代码:
private void panel1_MouseMove(object sender, MouseEventArgs e)
{

if (action2)
{
stetec = new SolidBrush(lbl_color.BackColor);
Graphics kp = panel1.CreateGraphics();
kp.FillEllipse(stetec, e.X, e.Y, 14, 14);
kp.Dispose();
}
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
action2 = false;


}

private void panel1_MouseDown(object sender, MouseEventArgs e)
{
action2 = true;
}

private void panel1_Paint(object sender, PaintEventArgs e)
{


} 
2个回答

16
首先,不要直接在MouseMove处理程序中执行绘图操作。将所有绘图代码保留在OnPaint覆盖中,并在那里使用提供的图形对象。只需在MouseMove处理程序内部维护一个点集合即可。原因之一是OnPaint将不可预测地被调用,而且您的绘图将被擦除,因为逻辑不会在OnPaint内执行。尝试最小化窗口,然后再将其最大化,以了解我的意思。
至于您的其他问题,就像我说的,只需维护一个Point对象的集合。重写OnPaint并使用Graphcis.DrawLines方法在其中绘制点集合。因此,您的代码变成了以下内容...
private void panel1_MouseMove(object sender, MouseEventArgs e)
{    
  if (action2)
  {
    myPointList.Add( e.Location );
    panel1.Invalidate(); //force a repaint
  }
}

private void panel1_Paint( object sender, PaintEventArgs e )
{
    e.Graphics.DrawLines( Pens.Black, myPointList );
}

我建议您对 Panel(或任何您使用的控件)进行子类化,并在那里放置绘图逻辑。在这种情况下,只需覆盖 OnPaint 方法,而不是处理 Paint 事件。
编辑:我认为我也应该评论一下为什么您的代码无法正常工作。您不会为鼠标穿过的每个像素接收到 MouseMove 事件。操作系统简单地不会给您那种级别的分辨率。相反,您将在间隔时间内获得事件。您可以在椭圆之间的间隙中看到此效果。您需要连接每个点之间的线条,这就是 DrawLines 方法将为您执行的操作。如果您在 MSPaint 中非常快速地绘制一条线,则可以看到同样的效果。该线将没有完美地遵循鼠标位置的好计数器,而是非常锯齿状。

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Adrian K

5
namespace Drawing
{
    public partial class Form1 : Form
    {
        bool draw = false;

        int pX = -1;
        int pY = -1;

        Bitmap drawing;

        public Form1()
        {
            InitializeComponent();

            drawing = new Bitmap(panel1.Width, panel1.Height, panel1.CreateGraphics());
            Graphics.FromImage(drawing).Clear(Color.White);
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (draw)
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Black, 14);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                panel1.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }

            pX = e.X;
            pY = e.Y;
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            draw = true;

            pX = e.X;
            pY = e.Y;
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            draw = false;
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImageUnscaled(drawing, new Point(0, 0));
        }
    }
}

此文同步发布于我的博客 - http://techtt.hassantt.com/2011/05/c-draw-on-panel.html


2
最好也在这里发布一下,以防那个页面在某些时候消失。 - Ed S.
@Hassan Voyeau,一个好主意是在你的代码中使用using语句 :) - ba__friend

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