how to make a crosshair cursor with help lines like this on screenshots:
I know how to make crosshire cursor:
this.Cursor = System.Windows.Forms.Cursors.Cross;
can be also something like that:
like in CAD software.
This is the code I use. x and y are the dimensions. In my case I can have some text on the cursor and this is name. If you want dots or dashes then you need to do that with the pen.
private Cursor crossCursor(Pen pen, Brush brush, string name, int x, int y) {
var pic = new Bitmap(x, y);
Graphics gr = Graphics.FromImage(pic);
var pathX = new GraphicsPath();
var pathY = new GraphicsPath();
pathX.AddLine(0, y / 2, x, y / 2);
pathY.AddLine(x / 2, 0, x / 2, y);
gr.DrawPath(pen, pathX);
gr.DrawPath(pen, pathY);
gr.DrawString(name, Font, brush, x / 2 + 5, y - 35);
IntPtr ptr = pic.GetHicon();
var c = new Cursor(ptr);
return c;
}
Just create two label box as lab_X_Axis and lab_Y_Axis.
In chart mousemove function code as shown below..
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
lab_X_Axis.Location = new Point((e.X), 21);
lab_Y_Axis.Location = new Point(76, e.Y);
}
private void Form1_Load(object sender, EventArgs e)
{
lab_X_Axis.AutoSize = false;
lab_Y_Axis.AutoSize = false;
lab_X_Axis.Text="";
lab_Y_Axis.Text="";
lab_X_Axes.Size = new Size(1, 300);
lab_Y_Axes.Size = new Size(300, 1);
}
Related
How to change the size of the image and the size of the rectangle that was drawn inside the image so that the rectangle does not lose the position of the x and the y.
I did the following code, but it doesn't keep the position of the rectangle
int index3 = dataGridView1.CurrentCell.RowIndex;
xxx = Convert.ToInt32(dataGridView1.Rows[index3].Cells[10].Value.ToString());
yyy = Convert.ToInt32(dataGridView1.Rows[index3].Cells[11].Value.ToString());
hhh = Convert.ToInt32(dataGridView1.Rows[index3].Cells[12].Value.ToString());
www = Convert.ToInt32(dataGridView1.Rows[index3].Cells[13].Value.ToString());
Rectangle r = new Rectangle(xxx, yyy, www, hhh);
int newX = (int)(xxx+ (xxx*0.2));
int newY = (int)(yyy +( yyy*0.2));
int newWidth = (int)(r.Width +(r.Width*0.2));
int newHeight = (int)(r.Height +(r.Height*0.2));
picturModule.Size = new Size((int)(picturModule.Width+(picturModule.Width*0.2)),(int)(picturModule.Height+(picturModule.Height*0.2)));
r = new Rectangle(newX, newY, newWidth, newHeight);
Pen pen = new Pen(Color.GreenYellow, 4);
picturModule.CreateGraphics().DrawRectangle(pen, r);
The problem is when changing the size of the image after drawing the
rectangle on the image, the rectangle is not moved to the correct X
and Y point and its position changes. I want when changing the size of
the image that the size of the rectangle changes and keeps the same
point from which you started
Okay. What you can do is store the position and size of the Rectangle as a "percentage" of the width/height of the image/picturebox. This could be done using RectangleF and floating point values.
Now you can use those "percentage" values and multiply them by the new picturebox width/height to get the scaled location and size.
Here's an example:
Code that generated the animation:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private bool drawRect = false;
private RectangleF rcF;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (drawRect)
{
Point pt = new Point((int)(rcF.X * pictureBox1.Width),
(int)(rcF.Y * pictureBox1.Height));
Size sz = new Size((int)(rcF.Width * pictureBox1.Width),
(int)(rcF.Height * pictureBox1.Height));
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(pt, sz));
}
}
private void button1_Click(object sender, EventArgs e)
{
Rectangle initialRectangle = new Rectangle(new Point(300, 150), new Size(125, 50));
PointF ptF = new PointF((float)initialRectangle.X / pictureBox1.Width,
(float)initialRectangle.Y / pictureBox1.Height);
SizeF szF = new SizeF((float)initialRectangle.Width / pictureBox1.Width,
(float)initialRectangle.Height / pictureBox1.Height);
rcF = new RectangleF(ptF, szF);
drawRect = true;
pictureBox1.Invalidate();
}
private void pictureBox1_SizeChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
}
I created in a Window Form 4 PictureBoxes (pictureBox1, pictureBox2, pictureBox3 and pictureBox4). I also created a function to draw a rectangle on a pictureBox like this:
To create the rectangle:
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
var x = e.X;
var y = e.Y;
var width = 10;
var height = 10;
FwRect = new[]
{
new PointF(x, y), new PointF(x, y + height), new PointF(x + width, y + height),
new PointF(x + width, y)
};
FwRectan = new Rectangle((int)x, (int)y, (int)width, (int)height);
Refresh();
}
Then I added this event for each pictureBox:
this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox3.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
this.pictureBox4.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
To draw the rectangle:
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, FwRectan);
}
}
Eventually, if I move the mouse inside the pictureBox1 and draw a rectangle, it also draw a rectangle for each pictureBox. How can I draw a rectangle only on the pictureBox that the mouse is located at?
Thank you very much!
You have 4 PictureBox, so you need 4 Rectangle to draw current mouse movement:
Rectangle[] _rectangle = new Rectangle[4];
then in both common PictureBox_MouseMove and PictureBox_Paint events you need to identify which value to use, index of picturebox. It can be done by using Tag property or by putting all pictureboxes into array so that their index there will match:
PictureBox _control = new PictureBox[] { pictureBox1, pictureBox2, pictureBox3, pictureBox4 };
The event handles will looks like this
void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
var x = e.X;
var y = e.Y;
var width = 10;
var height = 10;
FwRect = new[]
{
new PointF(x, y), new PointF(x, y + height), new PointF(x + width, y + height),
new PointF(x + width, y)
};
var index = _control.IndexOf(sender);
_rectangle[index] = new Rectangle((int)x, (int)y, (int)width, (int)height);
_rectangle[index].Invalidate();
}
void PictureBox_Paint(object sender, PaintEventArgs e)
{
var index = _control.IndexOf(sender);
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, _rectangle[index]);
}
}
Edit:
Actually above solution will remember rectangle for each picturebox. Might not be what you want. The simple fix would be to clear other rectangles in mousemove. Though the more proper solution would be to remember sender from mousemove and only paint matching sender in paint.
Here's an example showing how to store the Rectangle in the .Tag property as mentioned by Sinatr in his post. This example also clears the Rectangle when the mouse leaves so you only ever have one Rectangle being drawn in the current PictureBox:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.pictureBox1.MouseMove += this.PictureBox_MouseMove;
this.pictureBox2.MouseMove += this.PictureBox_MouseMove;
this.pictureBox3.MouseMove += this.PictureBox_MouseMove;
this.pictureBox4.MouseMove += this.PictureBox_MouseMove;
this.pictureBox1.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox2.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox3.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox4.MouseLeave += this.pictureBox_MouseLeave;
this.pictureBox1.Paint += this.PictureBox_Paint;
this.pictureBox2.Paint += this.PictureBox_Paint;
this.pictureBox3.Paint += this.PictureBox_Paint;
this.pictureBox4.Paint += this.PictureBox_Paint;
}
private int bxWidth = 10;
private int bxHeight = 10;
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pb = (PictureBox)sender;
pb.Tag = new Rectangle(e.X, e.Y, bxWidth, bxHeight);
pb.Invalidate();
}
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
PictureBox pb = (PictureBox)sender;
if (pb.Tag != null && pb.Tag is Rectangle)
{
Rectangle rc = (Rectangle)pb.Tag;
using (var pen = new Pen(Color.Black, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, rc);
}
}
}
private void pictureBox_MouseLeave(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
pb.Tag = null; // if you want the box to disappear when the mouse leaves?
pb.Invalidate();
}
}
Here's what it looks like running:
I have a pictureBox in c# and I have to move it by a vScrollBar.
It should be like this: (pseudo-code!)
if (scrollbar.ScrollUp)
{
int i = 0;
i += +1 per scroll
pictureBox.Location = new Point(0, i);
}
if (scrollbar.ScrollDown)
{
int k = 0;
k += -1 per scroll
pictureBox.Location = new Point(0, k);
}
I hope someone can understand my problem. Thanks
The example for the MSDN ScrollBar.Scroll event actually shows how to scroll a PictureBox.
Code from MSDN:
private void HandleScroll(Object sender, ScrollEventArgs e)
{
//Create a graphics object and draw a portion of the image in the PictureBox.
Graphics g = pictureBox1.CreateGraphics();
int xWidth = pictureBox1.Width;
int yHeight = pictureBox1.Height;
int x;
int y;
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
x = e.NewValue;
y = vScrollBar1.Value;
}
else //e.ScrollOrientation == ScrollOrientation.VerticalScroll
{
y = e.NewValue;
x = hScrollBar1.Value;
}
g.DrawImage(pictureBox1.Image,
new Rectangle(0, 0, xWidth, yHeight), //where to draw the image
new Rectangle(x, y, xWidth, yHeight), //the portion of the image to draw
GraphicsUnit.Pixel);
pictureBox1.Update();
}
Where HandleScroll is the event handler for the ScrollBar's Scroll event.
scrollBar1.Scroll += HandleScroll;
This is assuming you are trying to scroll the PictureBox. If you really just want to move it around, you could try the following:
private void HandleScroll(Object sender, ScrollEventArgs e)
{
var diff = scrollBar1.Value - e.NewValue;
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
pictureBox1.Location = new Point(diff, pictureBox1.Location.Y);
}
else //e.ScrollOrientation == ScrollOrientation.VerticalScroll
{
pictureBox1.Location = new Point(pictureBox1.Location.X, diff);
}
}
Warning, this code has not been tested.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var cp = new Point(Width / 2, Height / 2);
DrawGradientCircle(e.Graphics, cp, 100);
}
private void DrawGradientCircle(Graphics gr, Point cp, float radius)
{
var path = new GraphicsPath();
path.AddEllipse(cp.X - radius, cp.Y - radius, 2 * radius, 2 * radius);
using (var brush = new PathGradientBrush(path))
{
var blends = new ColorBlend(7);
blends.Colors[0] = Color.Violet;
blends.Positions[0] = 0;
blends.Colors[1] = Color.Blue;
blends.Positions[1] = 0.16f;
blends.Colors[2] = Color.Aqua;
blends.Positions[2] = 0.32f;
blends.Colors[3] = Color.Lime;
blends.Positions[3] = 0.48f;
blends.Colors[4] = Color.Yellow;
blends.Positions[4] = 0.64f;
blends.Colors[5] = Color.Orange;
blends.Positions[5] = 0.82f;
blends.Colors[6] = Color.Red;
blends.Positions[6] = 1;
brush.InterpolationColors = blends;
gr.FillPath(brush, path);
}
}
There is my code - i just want to draw the circle after button click, but how to do it?
But I don't know how make a link
If I understood you right, you could have a boolean variable and set it to true when you click the button... something like:
private bool _buttonClicked = false;
void myButton_Click(object sender, EventArgs e)
{
_buttonClicked = true;
this.Invalidate(); // <-- invalidate the form so it's repainted
this.Update(); // <-- optional: force a synchronous repaint
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if(!_buttonClicked) return;
// this will only happen after button is clicked
var cp = new Point(Width / 2, Height / 2);
DrawGradientCircle(e.Graphics, cp, 100);
}
Don't forget to assign myButton_Click to the button's Click event
Using below code I am able to draw arrow shaped button(shown below) ,but I want to draw hexagone(shown below as result image) ,so that I can use png image of size 175x154 as button image ,What Points I need to use to draw this ? and i need to to draw 6 such buttons ,how do i achieve this ?
private void Parent_Load(object sender, EventArgs e)
{
// Define the points in the polygonal path.
Point[] pts = {
new Point( 20, 60),
new Point(140, 60),
new Point(140, 20),
new Point(220, 100),
new Point(140, 180),
new Point(140, 140),
new Point( 20, 140)
};
// Make the GraphicsPath.
GraphicsPath polygon_path = new GraphicsPath(FillMode.Winding);
polygon_path.AddPolygon(pts);
// Convert the GraphicsPath into a Region.
Region polygon_region = new Region(polygon_path);
// Constrain the button to the region.
btnExam.Region = polygon_region;
// Make the button big enough to hold the whole region.
btnExam.SetBounds(
btnExam.Location.X,
btnExam.Location.Y,
pts[3].X + 5, pts[4].Y + 5);
}
The input should be a Rectangle which contains the Hexagonal shape, from that input we will calculate the Points for your Hexagonal shape, something like this:
public Point[] GetPoints(Rectangle container){
Point[] points = new Point[6];
int half = container.Height / 2;
int quart = container.Width/4;
points[0] = new Point(container.Left + quart, container.Top);
points[1] = new Point(container.Right - quart, container.Top);
points[2] = new Point(container.Right, container.Top + half);
points[3] = new Point(container.Right - quart, container.Bottom);
points[4] = new Point(container.Left + quart, container.Bottom);
points[5] = new Point(container.Left, container.Top + half);
return points;
}
private void Parent_Load(object sender, EventArgs e) {
//This should be placed first
// Make the button big enough to hold the whole region.
btnExam.SetBounds( btnExam.Location.X, btnExam.Location.Y, 100, 100);
// Make the GraphicsPath.
GraphicsPath polygon_path = new GraphicsPath(FillMode.Winding);
polygon_path.AddPolygon(GetPoints(btnExam.ClientRectangle));
// Convert the GraphicsPath into a Region.
Region polygon_region = new Region(polygon_path);
// Constrain the button to the region.
btnExam.Region = polygon_region;
}
You should update the Region whenever your btnExam's Size changes, so you should define some method called UpdateRegion and call it in a SizeChanged event handler:
private void UpdateRegion(){
GraphicsPath polygon_path = new GraphicsPath(FillMode.Winding);
polygon_path.AddPolygon(GetPoints(btnExam.ClientRectangle));
btnExam.Region = new Region(polygon_path);
}
//SizeChanged event handler for your btnExam
private void btnExam_SizeChanged(object sender, EventArgs e){
UpdateRegion();
}
//Then you just need to change the size of your btnExam in Parent_Load
private void Parent_Load(object sender, EventArgs e) {
//The button should be square
btnExam.SetBounds( btnExam.Location.X, btnExam.Location.Y, 100, 100);
}
Is this what you mean?
var xDisp = 10;
var yDisp = 10;
var length = 10;
var ls32 = (int)(length * Math.Sqrt(3) / 2.0);
var half = (int)(length / 2.0);
var points = new[]
{
new Point(xDisp + length, yDisp),
new Point(xDisp + half, yDisp + ls32),
new Point(xDisp - half, yDisp + ls32),
new Point(xDisp - length, yDisp),
new Point(xDisp - half, yDisp - ls32),
new Point(xDisp + half, yDisp - ls32)
};