NET programming.I have a image of a map with latitudes and longitudes on its borders .now when i drag the mouse on the map i should get a rectangle with one vertex at the mouse point and opposite one at the top left corner of map ,so that i can exactly pin pointedly locate the 开发者_Go百科pixel with latitude and longitude.to be clear it should appear as a rectangle when we drag mouse on the screen.I have a code which is partially working
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// "e.X" and "e.Y" are used to get MousePositionX and MousePositionY
rect = new Rectangle(e.X, e.Y, 0, 0);
this.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
// This makes sure that the left mouse button is pressed.
if (e.Button == MouseButtons.Left)
{
// Draws the rectangle as the mouse moves
rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
}
this.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, rect);
}
}
I don't know where the problem exactly is but could draw a rectangle at run time.any one please help me with changes in the code.
tafa's Answer works.
I only got two additions:
In the MouseDown Method you should also use the following code. So once you click somewhere in the map you get a rectangle even when not moving the mouse.
rect = new Rectangle(0, 0, e.X, e.Y);
In the MouseMove method I would use the following code, to not create new Rectangles whenever you move the mouse:
rect.Width = e.X; rect.Height = e.Y;
Two simple changes required;
Instead of this.Invalidate()
call pictureBox1.Invalidate()
.
In the mouseMove method generate rectangle as;
rect = new Rectangle(0, 0, e.X, e.Y);
Since you want the top left corner (0,0) be the other corner of the rectangle.
I would suggest creating your own canvas control ([Edit: which inherits from PictureBox]), with double buffering enabled. This will reduce flicker while drawing.
public partial class DrawingCanvas : PictureBox
{
public DrawingCanvas()
{
InitializeComponent();
SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw, true);
}
private Point start = new Point(0, 0);
private Point end = new Point(0, 0);
protected override void OnMouseDown(MouseEventArgs e)
{
start = e.Location;
end = e.Location;
Invalidate();
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
// This makes sure that the left mouse button is pressed.
if (e.Button == MouseButtons.Left)
end = e.Location;
Invalidate();
base.OnMouseMove(e);
}
protected override void OnPaint(PaintEventArgs e)
{
int top = start.Y < end.Y ? start.Y : end.Y;
int left = start.X < end.X ? start.X : end.X;
int width = end.X - start.X; if (width < 0) width = -width;
int height = end.Y - start.Y; if (height < 0) height = -height;
Rectangle rect = new Rectangle(left, top, width, height);
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, rect);
}
}
}
Note that DrawRectangle
doesn't accept negative width or height, so you must take care of this in the OnPaint
method.
Once you've added this control to your project, compile the project. Your custom control should be available on top of the Toolbox window in Visual Studio. If it isn't, you can either right click the Toolbox and select Choose Items...
to add your canvas to the toolbox, or simply add a Panel
control to your Form
, open the Form.Designer.cs
file, and replace all Panel
references with your DrawingCanvas
(or whatever name you choose).
When setting the background image, use the BackgroundImage
property.
精彩评论