Deleting Circles drawn on grids in C# Visual studio - c#

I have drawn a grid on form 8 in on paint event of the form as shown below. I have written a class drawRules in which I mentioned to draw the vertical and horizontal lines based on input from the form.
protected override void OnPaint(PaintEventArgs e)
{
Graphics g;
g = e.Graphics;
Pen linePen = new Pen(System.Drawing.Color.CornflowerBlue);
Int32 Num_of_Lines;
Int32 gridLength;
Int32 gridWidth;
bool IsIntValue = Int32.TryParse(Form7.setValue2, out Num_of_Lines);
bool IsIntValue1 = Int32.TryParse(Form7.setValue3, out gridWidth);
bool IsIntValue2 = Int32.TryParse(Form7.setValue4, out gridLength);
this.Size = new Size(Num_of_Lines * gridWidth, Num_of_Lines * gridLength);
if (IsIntValue)
{
if (IsIntValue1)
{
if (IsIntValue2)
{
drawRules.verticalRule vr1 = new drawRules.verticalRule(g, gridWidth, gridLength, Num_of_Lines);
//Draw horizontal line
drawRules.horizontalRule hr1 = new drawRules.horizontalRule(g, gridWidth, gridLength, Num_of_Lines);
}
linePen.Dispose();
base.OnPaint(e);
}
}
}
after this I want to draw circles wherever mouse is clicked for which I mentioned the mouse click event
private void Form8_MouseClick_1(object sender, MouseEventArgs e)
{
int r1 = e.X;
int r2 = e.Y;
Graphics g2;
g2 = this.CreateGraphics();
drawRules newclass1 = new drawRules();
newclass1.addcoordinate(r1, r2, g2);
}
addcoordinate1 is a method in drawRules class which is called to draw circle. Also, i am writing those coordinates in a file
public void addcoordinate(int r1, int r2, Graphics g2)
{
int gridWidth;
int gridLength;
int Num_of_Lines;
bool IsIntValue = Int32.TryParse(Form7.setValue2, out Num_of_Lines);
bool IsIntValue1 = Int32.TryParse(Form7.setValue3, out gridWidth);
bool IsIntValue2 = Int32.TryParse(Form7.setValue4, out gridLength);
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g2, rectangle);
Pen redPen1 = new Pen(Color.Red, 3);
DrawCircle(arg, redPen1, r1, r2, 8, 8);
System.IO.StreamWriter objWriter;
objWriter = new System.IO.StreamWriter("test.txt", true);
objWriter.Write(r1);
objWriter.Write(" ");
objWriter.Write(r2);
objWriter.WriteLine();
objWriter.Close();
}
public void DrawCircle(PaintEventArgs e, Pen redpen1, int x, int y, int
width, int height)
{
e.Graphics.DrawEllipse(redpen1, x - width / 2, y - height / 2, width, height);
redpen1.Dispose();
}
Now, I want to delete that circle, for which mouse is double clicked inside circle's area.
Please suggest how to delete the circles without deleting the grids behind. I will be grateful, if someone help me in this.

Don't draw in the code that gets executed when clicking the Button.
Save the coordinates and let the OnPaint methode handle it.
To remove your cirlces just remove them from the list.
private List<Point> circleCoordinates = new List<Point>();
public Form1()
{
InitializeComponent();
}
public void addcoordinate(int r1, int r2)
{
this.circleCoordinates.Add(new Point(r1, r2));
}
protected override void OnPaint(PaintEventArgs e)
{
// linedrawing goes here
foreach (Point point in this.circleCoordinates)
{
e.Graphics.DrawEllipse(Pens.Black, new Rectangle(point, new Size(10, 10)));
}
base.OnPaint(e);
}
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
{
for (int i = this.circleCoordinates.Count() - 1; i >= 0; i--)
{
Rectangle ellipseRectangle = new Rectangle(this.circleCoordinates[i].X - 5, this.circleCoordinates[i].Y - 5, 10, 10)
GraphicsPath path = new GraphicsPath();
path.AddEllipse(ellipseRectangle);
if(path.IsVisible(e.Location))
{
this.circleCoordinates.RemoveAt(i);
}
//invalidate form to trigger repainting
this.Invalidate();
}

Related

How to draw rectangle by coordinates of click?

I have pictureBox click event. I get coordinates of click and try t draw circle:
private void pictureMain_Click(object sender, EventArgs e){
MouseEventArgs me = (MouseEventArgs)e;
Point coordinates = me.Location;
int x = coordinates.X;
int y = coordinates.Y;
// Create pen.
Pen blackPen = new Pen(Color.Red, 2);
// Create rectangle for ellipse.
Rectangle rect = new Rectangle(x, y, 50, 50);
g.DrawEllipse(blackPen, rect);
}
But it draws circle not in coordinates(x,y) of picturebox. It places circle in another place.
Try this:
private void pictureBox1_Click (object sender, EventArgs e)
{
Point ellipseCenter = ((MouseEventArgs) e).Location;
Size ellipseSize = new Size (50, 50);
Point rectPosition = new Point (ellipseCenter.X - ellipseSize.Width / 2, ellipseCenter.Y - ellipseSize.Height / 2);
Rectangle rect = new Rectangle (rectPosition, ellipseSize);
using (Graphics grp = Graphics.FromImage (pictureBox1.Image))
{
grp.DrawEllipse (Pens.Red, rect);
}
pictureBox1.Refresh ();
}

I want to move Picturebox inside drew ellipse

I already drew ellipse using
g.DrawEllipse(p, 0, 0, 100, 100);
p = new Pen(Color.Red, 1f);
This is my code for moving picturbox
int x, y;
private void timer1_Tick(object sender, EventArgs e)
{
y+=5;
x += 2;
pictureBox3.Location = new Point(x, y);
Invalidate();
}
Picture box move in correctly ...
But I want ...How can i move Picturebox inside that ellipse?
Ellipse should be fixed one..

select two point to Draw a circle

I am using visual studio c# windows form, I need help to draw a circle using the Mouse click.. first click will give me the center of the circle equal to the cursor position and the second click will give me a point on the border of the circle equal to the second position of the cursor, the distance between the to points will give me the radius..now I have radius and point ..I can draw a circle ..The code doesn't work because I only can get one position of the cursor no matter how many times I click the mouse
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
int lastX = Cursor.Position.X;//the first click x cursor position
int lastY = Cursor.Position.Y;//the first click y cursor position,
//is there any way to reuse the Cursor.Position for different point ??
int x = Cursor.Position.X;//the second click x cursor position
int y = Cursor.Position.Y;//the second click y cursor position
Graphics g;
double oradius=Math.Sqrt(((lastX-x)^2) +((lastY-y)^2));
//double newy = Math.Sqrt(lastY);
// int newxv = Convert.ToInt32(newx);
int radius= Convert.ToInt32(oradius);
g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, x, y,radius,radius);
}
private void DrawCircle(PaintEventArgs e, int x, int y, int width, int height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
e.Graphics.DrawEllipse(pen, x - width / 2, y - height / 2, width, height);
}
}
You need to store the first click as well before you start doing the calculations. One way to do this is to create a class that simply throws an event every second time you pass it x and y coordinates like this:
public class CircleDrawer
{
private int _firstX;
private int _firstY;
private int _secondX;
private int _secondY;
private bool _isSecondClick;
private event EventHandler OnSecondClick;
public void RegisterClick(int x, int y)
{
if(_isSecondClick)
{
_secondX = x;
_secondY = y;
if(OnSecondClick != null)
OnSecondClick(this, null);
}
else
{
_firstX = x;
_firstY = y;
_isSecondClick = true;
}
}
}
You can then in your code simply call your methods:
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
int lastX = Cursor.Position.X;//the first click x cursor position
int lastY = Cursor.Position.Y;//the first click y cursor position,
_circleDrawer.RegisterClick(lastX, lastY);
}
And in your constuctor:
public MyForm()
{
_circleDrawer = new CircleDrawer();
_circleDrawer.OnSecondClick += DrawCircle();
}
public void DrawCircle()
{
// Your drawing code
}
Your lastX and lastY are local variables, and you initialize them in the beginning of the MouseDown event handler. They should be class level variables and should be populated at the end of the MouseDown event handler.
Also, you should test if they already have a value, and only if they have value then draw the circle and then clear them (so that the next circle will have it's own center).
Here is an improvement of your code. Note I've used the using keyword with the graphics object and with the pen - get used to use it every time you are using an instance of anything that's implementing the IDisposable interface.
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (_lastPosition != Point.Empty)
{
var currentPosition = Cursor.Position;
var oradius = Math.Sqrt(((_lastPosition.X - currentPosition.X) ^ 2) + ((_lastPosition.Y - currentPosition.Y) ^ 2));
var radius = Convert.ToInt32(oradius);
using (var g = this.CreateGraphics())
{
var arg = new PaintEventArgs(g, new Rectangle());
DrawCircle(arg, currentPosition, radius, radius);
}
_lastPosition = Point.Empty;
}
else
{
_lastPosition = Cursor.Position;
}
}
private void DrawCircle(PaintEventArgs e, Point position, int width, int height)
{
using (var pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3))
{
e.Graphics.DrawEllipse(pen, position.X - width / 2, position.Y - height / 2, width, height);
}
}
Note: This code can be improved even further.
There are many things fundamentally wrong with this code, here is a complete, working example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Point clickCurrent = Point.Empty;
private Point clickPrev = Point.Empty;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
clickPrev = clickCurrent;
clickCurrent = this.PointToClient(Cursor.Position);
if (clickPrev == Point.Empty) return;
Graphics g;
double oradius = Math.Sqrt((Math.Pow(clickPrev.X - clickCurrent.X, 2)) + (Math.Pow(clickPrev.Y - clickCurrent.Y, 2)));
int radius = Convert.ToInt32(oradius);
g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, clickPrev.X, clickPrev.Y, radius * 2, radius * 2);
clickCurrent = Point.Empty;
}
private void DrawCircle(PaintEventArgs e, int x, int y, int width, int height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
e.Graphics.DrawEllipse(pen, x - width / 2, y - height / 2, width, height);
}
}
private int _firstX;
private int _firstY;
private int _secondX;
private int _secondY;
private bool _isSecondClick;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (_isSecondClick)
{
_secondX = Cursor.Position.X;
_secondY = Cursor.Position.Y;
var radious1 = Math.Pow(_firstX - _secondX, 2);
var radious2 = Math.Pow(_firstY - _secondY, 2);
var radious = Math.Sqrt(radious1 + radious2);
Graphics g = this.CreateGraphics();
Rectangle rectangle = new Rectangle();
PaintEventArgs arg = new PaintEventArgs(g, rectangle);
DrawCircle(arg, _secondX, _secondY, radious, radious);
}
else
{
_firstX = Cursor.Position.X;
_firstY = Cursor.Position.Y;
_isSecondClick = true;
}
}
private void DrawCircle(PaintEventArgs arg, int x, int y, double width, double height)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 3);
var xL = Convert.ToInt32(x - width / 2);
var yL = Convert.ToInt32(y - height / 2);
var hL = Convert.ToInt32(height);
var wL = Convert.ToInt32(width);
arg.Graphics.DrawEllipse(pen, xL, yL, wL, hL);
}

How to undo the changes done in OnPaint Event in Winform?

I have drawn a region in C# Winform onPaint event. I dont want to have these changes in full screen mode. I have tried to save and restore the graphics but not able to do, please let me know if I'm missing something.
//class member
bool mFullSize = false;
GraphicsState transState;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Save translated graphics state.
Graphics gr = e.Graphics;
transState = gr.Save();
int x = 50;
int y = 50;
int width = 100;
int height = 100;
Rectangle rect = new Rectangle(x, y, width / 2, height / 2);
Region region = new Region(rect);
GraphicsPath path = new GraphicsPath();
path.AddPie(x, y, width, height, 180, 90);
region.Exclude(path);
if (!mFullSize)
{
gr.FillRegion(Brushes.Black, region);
}
else
{
gr.Restore(transState);
}
}
protected override void OnResize(EventArgs e)
{
if (this.WindowState == FormWindowState.Maximized)
{
mFullSize = true;
}
else
{
mFullSize = false;
}
}
Why don't you simply return when the Form is full sized? It's painted on maximization anyway, so I don't see no need to (re-)store any graphics state.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (WindowState == FormWindowState.Maximized) return; // just don't paint the things you don't want to
Graphics gr = e.Graphics;
int x = 50;
int y = 50;
int width = 100;
int height = 100;
Rectangle rect = new Rectangle(x, y, width / 2, height / 2);
Region region = new Region(rect);
GraphicsPath path = new GraphicsPath();
path.AddPie(x, y, width, height, 180, 90);
region.Exclude(path);
gr.FillRegion(Brushes.Black, region);
}
UPDATE: The problem is OnResize is not called when maximizing. You need to use OnSizeChanged or simply check the WindowState directly in your OnPaint method.
UPDATE2: First update was not completely correct (bug in debug-messages). OnResize is actually called. But you forgot to call base.OnResize and so OnPaint is not called.
So be sure to call base.OnResize in your overload. In your OnPaint you can check the WindowState directly and avoid painting if your Form is maximized.
protected override void OnResize(EventArgs e)
{
// DON'T FORGET TO CALL THE BASE METHOD
base.OnResize(e);
mFullSize = this.WindowState == FormWindowState.Maximized;
}

The buttons in project delete the squares?

I have problem with my C# winform project.
I have function that draw squares:
public void DrawingSquares(int x, int y)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Black, 5);
Rectangle myRectangle = new Rectangle(x, y, 100, 100);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
private void button1_Click(object sender, EventArgs e)
{
z = Convert.ToInt16(textBox1.Text)-1;
k = Convert.ToInt16(textBox2.Text)-1;
DrawAllSquares();
}
private void DrawAllSquares()
{
int tempy = y;
for (int i = 0; i < z; i++)
{
DrawingSquares(x, y);
for (int j = 0; j < k - 1; j++)
{
tempy += 50;
DrawingSquares(x, tempy);
}
x += 50;
tempy = y;
}
}
In my project, I have a function that I use to move button around the form at runtime, but when the button is moved onto the drawing the drawing is deleted.
What can I do to make the drawing permanent?
If you need permanently (in terms of application life time), by any means, you need to use it inside you Control's (the Control where rectangle is have to be drawn), OnPaint method.
If you need an animation too: it could be resolved by using a timer and changing coordinates that you pass like a parameters to your DrawSquares.
Hope this helps.
EDIT
A pseudocode:
public class MyControl : Control
{
public override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
DrawingSquares(e.Graphics, valueX, valueY);
}
public void DrawingSquares(Graphics graphicsObj, int x, int y)
{
Pen myPen = new Pen(System.Drawing.Color.Black, 5);
Rectangle myRectangle = new Rectangle(x, y, 100, 100);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
}
valueX and valueY are relative X and Y coordinates where you want the rectangle to be drawn.
These coordinates can be constant values, or you can change them from some timer and call Invalidate() on MyControl, so paint will be executed.

Categories