Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# drawing by mouse

Tags:

c#

drawing

I want to draw by mouse by e.X and e.Y. I know I should use list<Point> but I don't know how to do that. Unfortunately I have a problem with drawlines, I can't do that.

Somebody told me that I should use drawlines and not Fillellipse.

Here's the a picture of my current drawing and of the drawing I want to do:

drawing http://img.fileup.cz/?di=1413056646794

Here's the code:

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)
{


} 
like image 561
Franta Avatar asked May 17 '11 20:05

Franta


2 Answers

So, first off, don't perform your drawing directly inside of the MouseMove handler. Keep all of your drawing code in your OnPaint override and use the supplied graphics object there. Simply maintain a collection of points from within the MouseMove handler. The reason for this (well, one reason) is that OnPaint will be called unpredictably and your drawing will be wiped out because the logic will not be executed within OnPaint. Try minimizing your window and maximizing it again to see what I mean.

As for your other problem, like I said, simply maintain a collection of Point objects. Override OnPaint and draw the points there using the Graphcis.DrawLines method which accepts a collection of points. So your code becomes something like...

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 );
}

I would also suggest subclassing Panel (or whichever control you use) and placing the drawing logic there. In that case simply override the OnPaint method instead of handling the Paint event.

EDIT: I thought that I should also comment on why your code doesn't work. You will not receive a MouseMove event for every single pixel that the mouse traverses. The OS simply does not give you that level of resolution. Instead you will get the event at intervals. You can see this manifest in the gaps between your ellipses. You need to connect a line between each point, which is what the DrawLines method will do for you. You can see the same effect if you draw a line very rapidly in MSPaint. The line will not have nice counters that follow exactly where the mouse was, but instead the line will be very jagged.

like image 109
Ed S. Avatar answered Oct 21 '22 02:10

Ed S.


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));
        }
    }
}

Also posted on my blog - http://techtt.hassantt.com/2011/05/c-draw-on-panel.html

like image 23
Hassan Voyeau Avatar answered Oct 21 '22 02:10

Hassan Voyeau