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)
{
}
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With