In my code there are 2 graphics, the Graphics graphics and the Graphics g. The graphics are used to create the shapes and g is used to move the shapes using the arrow keys.In the code i have an eraser that is used for deleting what ever has been drawn by creating a pen that writes white when the cursor is clicked.With this logic of an eraser i had 0 problems until i intruduced the g graphics for moving the shapes.Now i cant find a way for the erasor to erase on the same graphics as the shape that moved(Notice that after creating a shape it will instantly be drawn in g graphics)the only close solution(which is the one i posted) i have found is this,but the problem is that when ever i click on the form, or i click a button to select a shape to draw what ever the eraser deleted disappears(that means the white color is removed for some reason)
Here i will include the most important parts of the code so you can get a feel of how everything works(The erasor code is in the mousemoves function)
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
startPoint = e.Location;
draw = true;
if (addtext)
{
TextBox textBox = new TextBox
{
Location = pictureBox1.PointToClient(MousePosition),
Size = new Size(100, 20),
ForeColor = Color.Black
};
textBox.Leave += (s, ev) =>
{
TextBox currentTextBox = (TextBox)s;
};
pictureBox1.Controls.Add(textBox);
textBox.Focus();
addtext = false;
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (draw)
{
if (choice == 1)
{
width = e.Location.X - startPoint.X;
height = e.Location.Y - startPoint.Y;
Rectangle shape = new Rectangle(startPoint.X, startPoint.Y, width, height);
graphics.DrawRectangle(pen, shape);
graphics.DrawRectangle(eraser, shape);
pictureBox1.Refresh();
draw = false;
}
else if (choice == 2)
{
width = e.Location.X - startPoint.X;
height = e.Location.Y - startPoint.Y;
Rectangle shape = new Rectangle(startPoint.X, startPoint.Y, width, height);
graphics.DrawEllipse(pen, shape);
graphics.DrawEllipse(eraser, shape);
pictureBox1.Refresh();
draw = false;
}
if (draw && choice == 3)
{
createPolygon(graphics, pen, startPoint, e.Location, 6);
createPolygon(graphics, eraser, startPoint, e.Location, 6);
draw = false;
}
else if (choice == 4)
{
createPolygon(graphics, pen, startPoint, e.Location, 4);
createPolygon(graphics, eraser, startPoint, e.Location, 4);
draw = false;
}
else if (choice == 5)
{
endPoint = e.Location;
graphics.DrawLine(pen, startPoint, endPoint);
graphics.DrawLine(eraser, startPoint, endPoint);
draw = false;
}
else if (choice == 6)
{
graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, Math.Abs(e.X - startPoint.X), Math.Abs(e.X - startPoint.X));
graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, Math.Abs(e.X - startPoint.X), Math.Abs(e.X - startPoint.X));
draw = false;
}
else if (choice == 7)
{
graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
draw = false;
}
else if (choice == 8)
{
Point[] point = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, e.Y), new Point(startPoint.X, e.Y) };
graphics.DrawPolygon(pen, point);
Point[] point2 = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, endPoint.Y), new Point(endPoint.X, endPoint.Y) };
graphics.DrawPolygon(eraser, point2);
draw = false;
}
else if (choice == 9)
{
Point[] point = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + e.X) / 2, e.Y), new Point(e.X, startPoint.Y) };
graphics.DrawPolygon(pen, point);
graphics.DrawPolygon(eraser, point);
draw = false;
}
else if (choice == 10)
{
graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
graphics.DrawEllipse(pen, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
graphics.DrawEllipse(eraser, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
draw = false; ;
}
Shape newShape = new Shape
{
Type = choice,
StartPoint = startPoint,
EndPoint = endPoint,
PenColor = pen.Color
};
shapes.Add(newShape);
pictureBox1.Refresh();
}
}
private void eraserToolStripMenuItem_Click(object sender, EventArgs e)//This is the box that is used for the erasing part
{
eraserMode = !eraserMode;
draw = true;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (eraserMode) //Here is the code for the Erasor
{
using (Graphics g = pictureBox1.CreateGraphics())
{
g.DrawLine(new Pen(Color.White, 6), startPoint, e.Location);
startPoint = e.Location;
}
}
if (draw && choice == 1)
{
width = e.Location.X - startPoint.X;
height = e.Location.Y - startPoint.Y;
graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);
graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, width, height);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 2)
{
width = e.Location.X - startPoint.X;
height = e.Location.Y - startPoint.Y;
graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);
graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, width, height);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 3)
{
createPolygon(graphics, eraser, startPoint, endPoint, 6);
createPolygon(graphics, pen, startPoint, e.Location, 6);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 4)
{
createPolygon(graphics, eraser, startPoint, endPoint, 4);
createPolygon(graphics, pen, startPoint, e.Location, 4);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 5)
{
graphics.DrawLine(eraser, startPoint, endPoint);
graphics.DrawLine(pen, startPoint, e.Location);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 6)
{
graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 7)
{
graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
endPoint = e.Location;
pictureBox1.Refresh();
}
else if (draw && choice == 8)
{
Point[] point2 = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, endPoint.Y), new Point(endPoint.X, endPoint.Y) };
Point[] point = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, e.Y), new Point(e.X, e.Y) };
graphics.DrawPolygon(eraser, point2);
graphics.DrawPolygon(pen, point);
endPoint = new Point(e.X, e.Y); // Update endPoint here
pictureBox1.Refresh();
}
else if (draw && choice == 9)
{
Point[] point4 = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + endPoint.X) / 2, endPoint.Y), new Point(endPoint.X, startPoint.Y) };
Point[] point3 = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + e.X) / 2, e.Y), new Point(e.X, startPoint.Y) };
graphics.DrawPolygon(eraser, point4);
graphics.DrawPolygon(pen, point3);
endPoint = new Point(e.X, e.Y); // Update endPoint here
pictureBox1.Refresh();
}
else if (draw && choice == 10)
{
graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
graphics.DrawEllipse(eraser, startPoint.X - 20, startPoint.Y - 20, (endPoint.X - startPoint.X) + 40, (endPoint.X - startPoint.X) + 40);
graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
graphics.DrawEllipse(pen, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
endPoint = e.Location;
pictureBox1.Refresh();
}
} //and the code that follows is the code that draws the shapes in the g graphics
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
foreach (var shape in shapes)
{
DrawShape(e.Graphics, shape);
}
}
private void DrawShape(Graphics g, Shape shape)
{
switch (shape.Type)
{
case 1:
g.DrawRectangle(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.Y - shape.StartPoint.Y)));
break;
case 2:
g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.Y - shape.StartPoint.Y)));
break;
case 3:
// Add logic for drawing hexagon (6-sided polygon)
createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 6);
break;
case 4:
// Add logic for drawing square (4-sided polygon)
createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 4);
break;
case 5:
g.DrawLine(new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint);
break;
case 6:
g.DrawRectangle(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
break;
case 7:
g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
break;
case 8:
createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 3);
break;
case 9:
createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 3);
break;
case 10:
// Add logic for drawing concentric circles
g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(new Point(shape.StartPoint.X - 20, shape.StartPoint.Y - 20), new Size(shape.EndPoint.X - shape.StartPoint.X + 40, shape.EndPoint.X - shape.StartPoint.X + 40)));
break;
}
}
You need a class to hold the two points of your "erased part":
public class ErasePoint {
public Point ptA;
public Point ptB;
public ErasePoint(Point a, Point b) {
ptA = a;
ptB = b;
}
}
Then you need a List to hold them, declared in the same place as your "shapes" List:
List<ErasePoint> erasePoints = new List<ErasePoint>();
Now, in your erase code, create an instance of ErasePoint, add it to the List, and Invalidate()
your PictureBox forcing it to redraw itself:
if (eraserMode) //Here is the code for the Erasor
{
ErasePoint erase = new ErasePoint(startPoint, e.Location);
erasePoints.Add(erase);
startPoint = e.Location;
pictureBox1.Invalidate();
}
In the Paint()
event, draw all the shapes first, then "erase" parts by drawing white on top of that:
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
// Draw all the shapes first
foreach (var shape in shapes)
{
DrawShape(e.Graphics, shape);
}
// Draw the "erased" parts:
using (Pen p = new Pen(Color.White, 6) {
foreach(ErasePoint ep in erasePoints) {
e.Graphics.DrawLine(p, ep.ptA, ep.ptB);
}
}
That's the basic idea; completely untested, of course...