Can not delete drawing line in c# - c#

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
isDrawing = true;
currentPoint = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Graphics bedLine = this.CreateGraphics();
Pen bedp = new Pen(Color.Blue, 2);
if (isDrawing)
{
bedLine.DrawLine(bedp, currentPoint, e.Location);
currentPoint = e.Location;
}
bedp.Dispose();
}
dont know how to delete a line, Drawn when mouse moves

It is a bad idea to draw on your form in any other method than OnPaint. You can not delete a line, it can only be drawn over.
So you should do all your drawing in an overriden OnPaint method. I suggest the following:
public partial class Form1
{
private bool isDrawing;
private Point startPoint;
private Point currentPoint;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
isDrawing = true;
startPoint = e.Location; // remember the starting point
}
// subscribe this to the MouseUp event of Form1
private void Form1_MouseUp(object sender, EventArgs e)
{
isDrawing = false;
Invalidate(); // tell Form1 to redraw!
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
currentPoint = e.Location; // save current point
Invalidate(); // tell Form1 to redraw!
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e); // call base implementation
if (!isDrawing) return; // no line drawing needed
// draw line from startPoint to currentPoint
using (Pen bedp = new Pen(Color.Blue, 2))
e.Graphics.DrawLine(bedp, startPoint, currentPoint);
}
}
This is what happens:
when the mouse is pressed, we save that position in startPoint and set isDrawing to true
when the mouse is moved, we save the new point in currentPoint and call Invalidate to tell Form1 that it should be redrawn
when the mouse is released, we reset isDrawing to false and again call Invalidate to redraw Form1 without a line
OnPaint draws Form1 (by calling the base implementation) and (if isDrawing is true) a line from startPoint to currentPoint
Instead of overriding OnPaint you can also subscribe to the Paint event of Form1 just as you did with the mouse event handlers

Related

How we move a label when mouse click on it and when mouse key up then stop moving inside a group box

When is try with code, there appear two label and when move, screen become white from where they move. I want single label move with mouse move.
bool mDown = false;
private void label13_MouseMove(object sender, MouseEventArgs e)
{
if (mDown)
{
label13.Location = e.Location;
}
}
private void label13_MouseDown(object sender, MouseEventArgs e)
{
mDown = true;
}
private void label13_MouseUp(object sender, MouseEventArgs e)
{
mDown = false;
}
The e.Location gives you a mouse position relative to the control that is being clicked. So to fix that, instead of
label13.Location = e.Location;
use
var pos = this.PointToClient(Cursor.Position);
label13.Location = new Point(pos.X - offset.X, pos.Y - offset.Y);`
Create the offset variable as a property of the form (type Point) and initialize it on the mouse down event:
offset = e.Location;

add multiple picturebox to a main Picturebox and draw them

I have a main PictureBox which adding to it , an other picture boxes; I pass the parent to the children and add them to the parent as follow :
public class VectorLayer : PictureBox
{
Point start, end;
Pen pen;
public VectorLayer(Control parent)
{
pen = new Pen(Color.FromArgb(255, 0, 0, 255), 8);
pen.StartCap = LineCap.ArrowAnchor;
pen.EndCap = LineCap.RoundAnchor;
parent.Controls.Add(this);
BackColor = Color.Transparent;
Location = new Point(0, 0);
}
public void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(pen, end, start);
}
public void OnMouseDown(object sender, MouseEventArgs e)
{
start = e.Location;
}
public void OnMouseMove(object sender, MouseEventArgs e)
{
end = e.Location;
Invalidate();
}
public void OnMouseUp(object sender, MouseEventArgs e)
{
end = e.Location;
Invalidate();
}
}
and am handling those On Events from inside the main PictureBox, now in the main PictureBox am handling on the Paint event as follow:
private void PicBox_Paint(object sender, PaintEventArgs e)
{
//current layer is now an instance of `VectorLayer` which is a child of this main picturebox
if (currentLayer != null)
{
currentLayer.OnPaint(this, e);
}
e.Graphics.Flush();
e.Graphics.Save();
}
but when I draw nothing appears , when I do Alt+Tab lose the focus from it , I see my vector , when I try to draw again and lose focus nothing happens..
why is that weird behavior and how do I fix it?
You have forgotten to hook up your events.
Add these lines to your class:
MouseDown += OnMouseDown;
MouseMove += OnMouseMove;
MouseUp += OnMouseUp;
Paint += OnPaint;
Not sure if you don't maybe want this in the MouseMove:
public void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
end = e.Location;
Invalidate();
}
}
Aslo these lines are useless and should be removed:
e.Graphics.Flush();
e.Graphics.Save();
GraphicsState oldState = Graphics.Save would save the current state, ie the setting of the current Graphics object. Useful if you need to toggle between several states, maybe scales or clipping or rotation or translation etc.. But not here!
Graphics.Flush flushes all pending graphics operations, but there is really no reason to suspect that there are any in your application.

Draw a fill rectangle dynamically on screen in C#

I would like to draw a fill rectangle dynamically on my screen, with an opacity at 0.1. The problem is that when i move the mouse, the previous rectangles aren't clear.
This is the drawing methods.
private void OnMouseDown(object sender, MouseEventArgs e)
{
isMouseDown = true;
x = e.X;
y = e.Y;
g = this.selectorForm.CreateGraphics();
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (!isMouseDown) return;
this.selectorForm.Invalidate();
g.FillRectangle(brush, this.getRectangle(x, y, e.X, e.Y));
g.DrawRectangle(pen, this.getRectangle(x, y, e.X, e.Y));
}
This is my selectorForm
internal class SelectorForm : Form
{
protected override void OnPaintBackground(PaintEventArgs e)
{
}
}
An example when I draw a rectangle (several overlapping rectangles)
And Invalidate() doesn't work because I override OnPaintBackground. But if I don't do this override, when I do this.selectorForm.Show(), my screen becomes gray.
So how can I draw a rectangle with an opacity 0.1 on my screen?
Thank you !
This is an example that works for me.
The crucial parts are:
using the Paint event and its Graphics
adding a Clear(BackgroundColor) or else I get the same artifacts you see
for transparency the TransparencyKey property should be used. There is a certain choice of colors:
Common colors may conflict with other things on the Form
Fuchsia works if you want to click through the Form
Other not so common colors are suitable; I chose a light green
You may want to adapt to your way of setting up events, I just did it this way for faster testing.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
DoubleBuffered = true;
Opacity = 0.1f;
// a color that will allow using the mouse on the form:
BackColor = Color.GreenYellow;
TransparencyKey = BackColor;
}
Point mDown = Point.Empty;
Point mCur = Point.Empty;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
mDown = e.Location;
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
mDown = Point.Empty;
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
mCur = e.Location;
Invalidate();
}
private void Form2_Paint(object sender, PaintEventArgs e)
{
if (mDown == Point.Empty) return;
Size s = new System.Drawing.Size(Math.Abs(mDown.X - mCur.X),
Math.Abs(mDown.Y - mCur.Y) );
Point topLeft = new Point(Math.Min(mDown.X, mCur.X),
Math.Min(mDown.Y, mCur.Y));
Rectangle r = new Rectangle(topLeft, s);
e.Graphics.Clear(this.BackColor); // <--- necessary!
e.Graphics.FillRectangle(Brushes.Bisque, r ); // <--- pick your..
e.Graphics.DrawRectangle(Pens.Red, r); // <--- colors!
}
}
}
You can try following code:
g.Clear();
g.FillRectangle(brush, this.getRectangle(x, y, e.X, e.Y));
g.DrawRectangle(pen, this.getRectangle(x, y, e.X, e.Y));

In a PictureBox, drawing a temporary circle on mouse down, to follow the mouse, until the mouseUp event is detected

I'm really new to drawing in C#, and I'm using Windows Forms instead of WPF, so maybe I'm doing it wrong from the get-go... you tell me... but I'd like to have a temporary marker put down on the PictureBox (on MouseDown) that will follow the mouse (erasing the previous drawings of itself, i.e. not leaving a trail), and then being drawn in the final position on the MouseUp event.
Here's some skeleton code that you guys can fill in:
bool mDown;
Graphics g; // initialized to pictureBox1.CreateGraphics() on Form_Load, though
// I am unsure how that differs from Graphics.FromImage(pictureBox1)
SolidBrush sbGray, sbGreen;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mDown = true;
// store/push initial drawing
g.FillEllipse(sbGray, e.X - 5, e.Y - 5, 10, 10);
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (mDown)
{
// restore/pop initial drawing, erasing old trail
g.FillEllipse(sbGray, e.X - 5, e.Y - 5, 10, 10);
}
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
// restore/pop initial drawing, erasing old trail
g.FillEllipse(sbGreen, e.X - 5, e.Y - 5, 10, 10);
mDown = false;
}
I suppose there are several ways to skin a cat, such as changing the mouse icon, so perhaps this is not even the best way to do it? Even so, I will probably need to know the answers to both questions -- whether there is a better way to do it, and also how to extract the graphics from a PictureBox (as this knowledge will most likely prove useful later anyways.)
(Note: Although the gray circles should erase themselves, the green circles should be persistent and multiple green circles should be capable of existing in the PictureBox at the same time.)
You need to look at the PictureBox's Paint Event also, it is better to do all of your graphics in the Paint event since you do not have to worry about disposing the Graphic Object.. See if this is what you were wanting.
Edit: added code to retain points and also to clear them.
public partial class Form1 : Form
{
bool mDown;
SolidBrush sbGray = new SolidBrush(Color.Gray);
SolidBrush sbGreen = new SolidBrush(Color.LimeGreen);
SolidBrush sbTemp;
Point mPosition = new Point();
public List<Point> points = new List<Point>();
public Form1()
{
InitializeComponent();
pictureBox1.Image = Image.FromFile(#"C:\Temp\Test.jpg");
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mDown = true;
mPosition = new Point(e.X, e.Y);
sbTemp = sbGray;
pictureBox1.Invalidate();
}
else
{
points.Clear();
sbTemp = null;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (mDown)
{
mPosition = new Point(e.X, e.Y);
sbTemp = sbGray;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mPosition = new Point(e.X, e.Y);
points.Add(mPosition);
sbTemp = sbGreen;
pictureBox1.Invalidate();
mDown = false;
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (sbTemp != null)
{
e.Graphics.FillEllipse(sbTemp, mPosition.X -5, mPosition.Y -5, 10, 10);
}
if (points != null)
{
foreach (var loc in points)
{
e.Graphics.FillEllipse(sbGreen, loc.X - 5, loc.Y - 5, 10, 10);
}
}
}
}

How can I move windows when Mouse Down

we able to move windows forms when we mouse down on title bar .
but how can I move windows when mouse down in form ?
You'll need to record when the mouse is down and up using the MouseDown and MouseUp events:
private bool mouseIsDown = false;
private Point firstPoint;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
firstPoint = e.Location;
mouseIsDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
As you can see, the first point is being recorded, so you can then use the MouseMove event as follows:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseIsDown)
{
// Get the difference between the two points
int xDiff = firstPoint.X - e.Location.X;
int yDiff = firstPoint.Y - e.Location.Y;
// Set the new point
int x = this.Location.X - xDiff;
int y = this.Location.Y - yDiff;
this.Location = new Point(x, y);
}
}
You can do it manually by handling the MouseDown event, as explained in other answers. Another option is to use this small utility class I wrote some time ago. It allows you to make the window "movable" automatically, without a line of code.
Listen for the event when the mouse button goes down in the form and then listen for mouse moves until it goes up again.
Here's a codeproject article that shows how to do this: Move window/form without Titlebar in C#
You can't use location provided in MouseUp or Down, you should use system location like this
private Point diffPoint;
bool mouseDown = false;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
//saves position difference
diffPoint.X = System.Windows.Forms.Cursor.Position.X - this.Left;
diffPoint.Y = System.Windows.Forms.Cursor.Position.Y - this.Top;
mouseDown = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
this.Left = System.Windows.Forms.Cursor.Position.X - diffPoint.X;
this.Top = System.Windows.Forms.Cursor.Position.Y - diffPoint.Y;
}
}
This works, tested.

Categories