The image draws itself before I click Draw
The image draws itself before I click Draw
In the application, I am trying to draw a shape with user defined width and height. Then when it draws, I try to modify its stroke thickness.
Like this:
It's all good until I save it as an object and redraws it over and over. When I try to draw something again, and try to scale up the stroke thickness and scale down, it leaves the drawing in GRAY that of which is only applicable when the drawing is accepted. The Red Line is the current shape drawn and the gray on its back is my problem. I haven't accepted it yet.
Here's the code:
Main Form
public partial class Form1 : Form
public Form1()
InitializeComponent();
cbox_Grid.Checked =true;
pictureBox_Canvass.Paint += draw.ShowGrid;
Draw draw = new Draw();
Shape s = new Shape();
Shape.Buttons buttons = new Shape.Buttons();
int rX, rY, rW, rH; //Rectangle Variables
int strokeRect;
private void cbox_Grid_CheckedChanged(object sender, EventArgs e)
if (cbox_Grid.Checked)
pictureBox_Canvass.Paint += draw.ShowGrid;
pictureBox_Canvass.Paint += DrawAll;
pictureBox_Canvass.Refresh();
else
pictureBox_Canvass.Paint += draw.ClearCanvass;
pictureBox_Canvass.Paint += DrawAll;
pictureBox_Canvass.Refresh();
#region Shape Buttons
private void btn_Rectangle_Click(object sender, EventArgs e)
this.tbox_Width.Text = "60";
this.tbox_Height.Text = "30";
buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "rectangle");
HideButtons();
ShowSettings();
private void btn_Square_Click(object sender, EventArgs e)
buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "square");
this.tbox_Width.Text = "60";
this.tbox_Height.Text = "60";
HideButtons();
ShowSettings();
private void btn_Circle_Click(object sender, EventArgs e)
buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "circle");
this.tbox_Width.Text = "60";
this.tbox_Height.Text = "60";
HideButtons();
ShowSettings();
private void btn_Ellipse_Click(object sender, EventArgs e)
buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "ellipse");
this.tbox_Width.Text = "60";
this.tbox_Height.Text = "30";
HideButtons();
ShowSettings();
private void btn_Triangle_Click(object sender, EventArgs e)
buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "triangle");
this.tbox_Width.Text = "60";
this.tbox_Height.Text = "60";
HideButtons();
ShowSettings();
#endregion
#region Draw Button Event
private void btn_Draw_Click(object sender, EventArgs e)
pictureBox_Canvass.Refresh();
if(cbox_Grid.Checked)
switch (buttons)
case Shape.Buttons.rectangle:
pictureBox_Canvass.Paint += draw.ShowGrid;
pictureBox_Canvass.Paint += DrawAll;
pictureBox_Canvass.Paint += DrawRect;
pictureBox_Canvass.Refresh();
break;
case Shape.Buttons.square:
break;
case Shape.Buttons.circle:
break;
case Shape.Buttons.ellipse:
break;
case Shape.Buttons.triangle:
break;
else
switch (buttons)
case Shape.Buttons.rectangle:
pictureBox_Canvass.Paint += DrawAll;
pictureBox_Canvass.Paint += DrawRect;
pictureBox_Canvass.Refresh();
break;
case Shape.Buttons.square:
break;
case Shape.Buttons.circle:
break;
case Shape.Buttons.ellipse:
break;
case Shape.Buttons.triangle:
break;
#endregion
#region PaintEvents
public void DrawRect(object sender, PaintEventArgs e)
rX = (((486 / 2) - (Convert.ToInt32((Convert.ToInt32(tbox_Width.Text) * 96) / 25.4)) / 2));
rY = (((486 / 2) - (Convert.ToInt32((Convert.ToInt32(tbox_Height.Text) * 96) / 25.4)) / 2));
rW = (Convert.ToInt32((Convert.ToInt32(tbox_Width.Text) * 96) / 25.4));
rH = (Convert.ToInt32((Convert.ToInt32(tbox_Height.Text) * 96) / 25.4));
Shape shape = new Shape();
strokeRect = trackBar_Stroke.Value;
shape.strokeThickness = strokeRect;
shape.acceptRectangle(Color.Red, strokeRect, new PointF(rX, rY), rW, rH, e.Graphics);
public void AcceptRect(object sender, PaintEventArgs e)
Shape shape = new Shape();
shape.color = Color.Gray;
shape.strokeThickness = this.strokeRect;
shape.points = new PointF(rX, rY);
shape.width = rW;
shape.height = rH;
shape.DrawRectangle(Color.Gray, strokeRect, new PointF(rX, rY), rW, rH, e.Graphics);
s._shapes.Add(shape);
#endregion
public void DrawAll(object sender, PaintEventArgs e)
foreach (Shape shapes in s._shapes)
s.acceptRectangle(shapes.color, shapes.strokeThickness, shapes.points, shapes.width, shapes.height, e.Graphics);
#region Accept-Reset-Cancel
private void btn_Accept_Click(object sender, EventArgs e)
switch (buttons)
case Shape.Buttons.rectangle:
pictureBox_Canvass.Paint += AcceptRect;
pictureBox_Canvass.Refresh();
break;
case Shape.Buttons.square:
break;
case Shape.Buttons.circle:
break;
case Shape.Buttons.ellipse:
break;
case Shape.Buttons.triangle:
break;
HideSettings();
ShowButtons();
private void btn_Cancel_Click(object sender, EventArgs e)
HideSettings();
ShowButtons();
private void btn_Reset_Click(object sender, EventArgs e)
s._shapes.Clear();
rX = 0;
rY = 0;
rW = 0;
rH = 0;
if(cbox_Grid.Checked)
pictureBox_Canvass.Paint += draw.ClearCanvass;
pictureBox_Canvass.Paint += draw.ShowGrid;
pictureBox_Canvass.Refresh();
else
pictureBox_Canvass.Paint += draw.ClearCanvass;
pictureBox_Canvass.Refresh();
HideSettings();
ShowButtons();
#endregion
#region Methods for Hide and Show
public void HideButtons()
btn_Rectangle.Visible = false;
btn_Square.Visible = false;
btn_Ellipse.Visible = false;
btn_Circle.Visible = false;
btn_Triangle.Visible = false;
public void ShowButtons()
btn_Rectangle.Visible = true;
btn_Square.Visible = true;
btn_Ellipse.Visible = true;
btn_Circle.Visible = true;
btn_Triangle.Visible = true;
public void HideSettings()
btn_Draw.Visible = false;
btn_Accept.Visible = false;
btn_Cancel.Visible = false;
btn_Reset.Visible = false;
btn_Accept.Visible = false;
trackBar_Size.Visible = false;
trackBar_Stroke.Visible = false;
trackBar_Corner.Visible = false;
label_Corner.Visible = false;
label_Height.Visible = false;
label_Size.Visible = false;
label_Stroke.Visible = false;
rb_Both.Visible = false;
rb_Height.Visible = false;
rb_Width.Visible = false;
tbox_Height.Visible = false;
tbox_Width.Visible = false;
label_Width.Visible = false;
public void ShowSettings()
btn_Draw.Visible = true;
btn_Accept.Visible = true;
btn_Cancel.Visible = true;
btn_Reset.Visible = true;
btn_Accept.Visible = true;
trackBar_Size.Visible = true;
trackBar_Stroke.Visible = true;
trackBar_Corner.Visible = true;
label_Corner.Visible = true;
label_Height.Visible = true;
label_Size.Visible = true;
label_Stroke.Visible = true;
rb_Both.Visible = true;
rb_Height.Visible = true;
rb_Width.Visible = true;
tbox_Height.Visible = true;
tbox_Width.Visible = true;
label_Width.Visible = true;
#endregion
#region Size Scaling
private void trackBar_Stroke_Scroll(object sender, EventArgs e)
pictureBox_Canvass.Refresh();
switch (buttons)
case Shape.Buttons.rectangle:
strokeRect = trackBar_Stroke.Value;
break;
case Shape.Buttons.square:
break;
case Shape.Buttons.circle:
break;
case Shape.Buttons.ellipse:
break;
case Shape.Buttons.triangle:
break;
;
#endregion
#region Stroke Scaling
private void trackBar_Size_Scroll(object sender, EventArgs e)
switch (buttons)
case Shape.Buttons.rectangle:
break;
case Shape.Buttons.square:
break;
case Shape.Buttons.circle:
break;
case Shape.Buttons.ellipse:
break;
case Shape.Buttons.triangle:
break;
pictureBox_Canvass.Refresh();
#endregion
Shape Class
public class Shape
public Draw draw;
public float width;
public float height;
public float x;
public float y;
public PointF points;
public int strokeThickness;
public Color color;
public List<Shape> _shapes = new List<Shape>();
public float acceptedStroke;
public enum Buttons
rectangle, square, circle, ellipse, triangle
public void DrawRectangle(Color c, int stroke, PointF points, float w, float h,Graphics g)
this.points = points;
this.width = w;
this.height = h;
this.strokeThickness = stroke;
g.DrawRectangle(new Pen(c,stroke), points.X, points.Y,w,h);
public void acceptRectangle(Color c, int stroke, PointF points, float w, float h, Graphics g)
this.points = points;
this.width = w;
this.height = h;
this.acceptedStroke = stroke;
g.DrawRectangle(new Pen(c, stroke), points.X, points.Y, w, h);
2 Answers
2
In your Shape Class
//Methods
public void DrawRectangle(Color c, int stroke, float w, float h, Graphics g, float radius)
this.width = w;
this.height = h;
this.strokeThickness = stroke;
this.type = ShapeType.rectangle;
this.radius = radius;
//Centering the Shape
PointF points = new PointF();
//w -= strokeThickness;
//h -= strokeThickness;
points.X = (center.X - ((w) / 2f));
points.Y = (center.Y - ((h) / 2f));
//Aliasing for smooth graphics when drawing and resizing
g.InterpolationMode = InterpolationMode.High;
//Drawing
RectangleF rect = new RectangleF(points.X, points.Y, w, h);
GraphicsPath path = this.GetRoundedRect(rect, radius);
g.DrawPath(new Pen(c, stroke), path);
public void DrawSquare(Color c, int stroke, float w, float h, Graphics g, float radius)
this.width = w;
this.height = h;
this.strokeThickness = stroke;
this.type = ShapeType.square;
this.radius = radius;
//w -= strokeThickness;
//h -= strokeThickness;
//Centering the Shape
PointF points = new PointF();
points.X = (center.X - (w / 2));
points.Y = (center.Y - (h / 2) + DefaultOffset);
//Aliasing for smooth graphics when drawing and resizing
g.InterpolationMode = InterpolationMode.High;
//Drawing
RectangleF rect = new RectangleF(points.X, points.Y, w, h);
GraphicsPath path = this.GetRoundedRect(rect, radius);
g.DrawPath(new Pen(c, stroke), path);
public void DrawCircle(Color c, int stroke, float w, float h, Graphics g)
this.width = w;
this.height = h;
this.strokeThickness = stroke;
this.type = ShapeType.circle;
PointF points = new PointF();
//Centering the Shape
points.X = (float)((center.X - (w/ 2)));
points.Y = (float)((center.Y - (h / 2)));
//Aliasing for smooth graphics when drawing and resizing
g.SmoothingMode = SmoothingMode.AntiAlias;
//Drawing
RectangleF rect = new RectangleF(points.X, points.Y, w, h);
g.DrawEllipse(new Pen(c, stroke), rect);
public void DrawEllipse(Color c, int stroke, float w, float h, Graphics g)
this.width = w;
this.height = h;
this.strokeThickness = stroke;
this.type = ShapeType.ellipse;
//Centering the Shape
PointF points = new PointF();
points.X = (center.X - (w / 2));
points.Y = (center.Y - (h / 2));
//Aliasing for smooth graphics when drawing and resizing
g.SmoothingMode = SmoothingMode.AntiAlias;
//Drawing
RectangleF rect = new RectangleF(points.X, points.Y, w, h);
g.DrawEllipse(new Pen(c, stroke), rect);
public void DrawTriangle(Color c, int stroke, float w, Graphics g, float radius)
this.strokeThickness = stroke;
this.type = ShapeType.triangle;
float h = (float)((w * (Math.Sqrt(3))) / 2);
PointF points = new PointF();
points.Y = (int)(((center.Y - h) + (h / 3f)) + DefaultOffset);
points.X = (int)center.X - (w / 2f);
this.size = new SizeF(w, h);
this.location = points;
//Calculation of the triangle points
RectangleF rect = new RectangleF(this.location, this.size);
PointF A = new PointF(rect.X, rect.Y + rect.Height);
PointF B = new PointF(rect.X + (rect.Width / 2f), rect.Y);
PointF C = new PointF(rect.Right, rect.Y + rect.Height);
//Drawing
GraphicsPath path = this.DrawRoundedTriangle(rect, A, B, C, radius);
g.DrawPath(new Pen(c, stroke), path);
#endregion
Call them here
private void pictureBox_Canvass_Paint(object sender, PaintEventArgs e)
case Shape.ShapeType.rectangle:
shape.DrawRectangle(rectangleColor, strokeRect, rectangleWidth, rectangleHeight, e.Graphics, rectRadius);
break;
case Shape.ShapeType.square:
shape.DrawSquare(squareColor, strokeSquare, squareWidth, squareHeight, e.Graphics, squareRadius);
break;
case Shape.ShapeType.circle:
shape.DrawCircle(circleColor, strokeCircle, circleWidth, circleHeight, e.Graphics);
break;
case Shape.ShapeType.ellipse:
shape.DrawEllipse(ellipseColor, strokeEllipse, ellipseWidth, ellipseHeight, e.Graphics);
break;
case Shape.ShapeType.triangle:
shape.DrawTriangle(triangleColor, strokeTriangle, triangleWidth, e.Graphics, triangleRadius);
break;
Event handlers are lists. When you do this:
pictureBox_Canvass.Paint += draw.ShowGrid;
You add draw.ShowGrid
to the list of methods that are called when your pictureBox_Canvass
needs drawing. You keep doing that over and over for multiple methods, never removing them, so all your methods are going to be called multiple times every time your pictureBox_Canvass
needs redrawing.
draw.ShowGrid
pictureBox_Canvass
pictureBox_Canvass
This is completely wrong. Remove everything like pictureBox_Canvass.Paint +=
from your code except from your form constructor. You need only one Paint handler for your pictureBox_Canvass
which should be created when you create your form and never change it. In fact, if you use the Visual Studio design view you probably already have one of these; click your pictureBox in design view and double-click the Paint event in the Properties panel, it will open the Paint handler.
pictureBox_Canvass.Paint +=
pictureBox_Canvass
In that handler you need to draw only the lines you want. You need a form variable or something to hold the shape and its coordinates. Set that variable and call pictureBox_Canvass.Invalidate()
when you click your button and draw it in the Paint handler.
pictureBox_Canvass.Invalidate()
An extremely simple example is in How to draw shapes in WinForms.
Read the linked question; you do something like
e.Graphics.FillRectangle(Brushes.DarkGray, rect)
where rect
is set by one of your buttons.– Dour High Arch
Sep 11 '18 at 0:58
e.Graphics.FillRectangle(Brushes.DarkGray, rect)
rect
I have another question @Dour, the picturebox seems lagging when scaling. Is there anything I can do to fix that?
– TerribleDog
Sep 11 '18 at 2:46
Nevermind, Fixed it. Thanks a lot !!
– TerribleDog
Sep 11 '18 at 2:59
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks for the answer. Now what do I put inside " private void pictureBox_Canvass_Paint(object sender, PaintEventArgs e) in order to draw?" @Dour
– TerribleDog
Sep 11 '18 at 0:57