How to use the Paint event to draw shapes at mouse coordinates
The PaintEventArgs
allows you to access to the Graphics
object, you need that one to draw something.
If you don't want to use the PaintEventArgs
, i suggest that you call the CreateGraphics()
method of your Form
, and it will allow you to draw the rectangle.
To improve performance, i suggest that you use the using(...){ } keywork in order to dispose the Graphics
object and the Pen
object.
You need to include System.Drawing
in order to use Graphics
and Pen
.
You're code will look like that :
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
Point _coordinates;
public Form1()
{
this._coordinates = new Point();
this.InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void Form1_MouseMove(object sender, MouseEventArgs e)
{
this._coordinates = new Point(e.X, e.Y);
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
// Don't draw on first Paint event
if(this._coordinates.X != 0 && this._coordinates.Y != 0)
{
this.DrawRect(e);
}
}
public void DrawRect(PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Azure, 4))
{
Rectangle rect = new Rectangle(0, 0, this._coordinates.X, this._coordinates.Y);
e.Graphics.DrawRectangle(pen, rect);
}
}
}
}
Drawing rectangles on picture box
NEVER call CreateGraphics
. If you want to draw on a control, handle the Paint
event of that control and use the e.Graphics
property provided. If the drawing needs to change, store the data that describes the drawing in one or more fields, then read those fields in the Paint
event handler. If you need to force the drawing to change, modify those fields and then call Invalidate
on the control. Ideally, pass an argument to that Invalidate
method that describes the smallest area that has or might have changed. Here's one I and a friend prepared earlier.
Note that WinForms controls are painted and repainted quite often, so any drawing done outside the Paint
event handler is likely to be wiped. That's exactly what's happening in the cases that you say are not working. The drawing is being done but is then wiped. By doing your drawing in the Paint
event handler, you ensure that it is reinstated every time it is wiped, so it appears permanent.
Draw a moving point on a fixed draw
Once a circle has been drawn, there is no way to delete it. So, you need to clear the entire canvas with the background color and redraw everything.
So, you need to:
Come up with a bunch of "shape" classes for representing each line and each ark and each circle. They will probably all derive from some common base "Shape" class which offers methods that are common to all shapes, for example, a method to draw the shape on a canvas.
Instantiate objects from these classes to represent the shapes that are supposed drawn on the screen, and keep these objects in a list throughout the lifetime of your application.
When the event occurs, you make any changes to your shapes, (in your case, remove a circle and add another circle, or, more likely, change the coordinates of an existing circle without removing it and re-inserting it in the list,) and then you need to invalidate the canvas control that you presumably use for painting, (search for "Invalidate" for documentation,) so as to cause the canvas to repaint itself.
You override the paint method of the canvas control so as to do your painting: first you clear the control to its background color, and then you iterate through your list of shapes, calling each shape to draw itself on the canvas.
Of course this will cause flicker; if that's unacceptable, then you will need to read up on how to implement "double buffering" (look it up) to eliminate the flicker.
Another approach for flicker elimination is to only erase and repaint the area that has changed. In your case, that would be the smallest rectangle that contains both the circle in its old location, and the circle in its new location. So, instead of invalidating the entire canvas, you invalidate only that rectangle. The problem with this approach is that other shapes that cross the invalidated area might appear to be redrawn somewhat inaccurately. This may be unacceptable, or it may be acceptable, you will not know unless you try it.
Related Topics
How to Filter All HTML Tags Except a Certain Whitelist
Is There a Jquery-Like CSS/HTML Selector That Can Be Used in C#
Adding Stylesheets Programmatically in ASP.NET
Calling Unix and Linux Shared Object File .So from C#
Ide's for C# Development on Linux
Bundler Not Including .Min Files
Accessing MVC's Model Property from JavaScript
How to Post an Array of Complex Objects with JSON, Jquery to ASP.NET MVC Controller
Running Scripts in HTMLagilitypack
How Does the Ternary Operator Work
What Is the Equivalent of the Java Bigdecimal Class in C#
Scraping Webpage Generated by JavaScript with C#
Marshal C++ Struct Array into C#
How to Unserialize PHP Serialized Array/Variable/Class and Return Suitable Object in C#