Hi i would like to know how can i get points from the second line i draw. Here is my code, for now i can draw lines with mouse event and draw lines with a button where i write the coordinates of the points.
public partial class Form1 : Form
{
Graphics drawArea;
private Point p1, p2;
List p1List = new List();
List p2List = new List();
public Form1()
{
InitializeComponent();
drawArea = panel1.CreateGraphics();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = CreateGraphics();
Pen p = new Pen(System.Drawing.Color.Black, 1);
for (int x = 0; x < p1List.Count; x++)
{
drawArea.DrawLine(p, p1List[x], p2List[x]);
}
}
private void button1_Click(object sender, EventArgs e)
{
p1.X = Convert.ToInt32(textBox1.Text);
p1.Y = Convert.ToInt32(textBox3.Text);
p2.X = Convert.ToInt32(textBox2.Text);
p2.Y = Convert.ToInt32(textBox4.Text);
Pen p = new Pen(System.Drawing.Color.Black, 2);
drawArea.DrawLine(p, p1.X, p1.Y, p2.X, p2.Y);
}
void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (p1.X == 0)
{
p1.X = e.X;
p1.Y = e.Y;
}
else
{
p2.X = e.X;
p2.Y = e.Y;
p1List.Add(p1);
p2List.Add(p2);
panel1.Invalidate();
p1.X = 0;
}
}
}
}
Related
I have tried using the following code:
pictureBox1.Invalidate();
//or
pictureBox1.Update();
//or
Refresh();
But it just did nothing on it. I want to clear all the drawn graphics on my picture box as after I click the next page I want to draw the new rectangles on it. So, please don't provide me such a solution:
g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height))
or
Graphics.Clear();
Anyone want to share the solution with me? I am appreciated with it.
page 2
page 3
Form2.cs
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Red, 2);
e.Graphics.DrawRectangle(pen, rect);
}
bool draw;
int x_start, y_start;
Rectangle rect;
//UserRect rect;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
}
else if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
pictureBox1.Cursor = Cursors.Cross;
draw = true;
x_start = e.X;
y_start = e.Y;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
}else if(e.Button == MouseButtons.Right)
{
pictureBox1.Cursor = Cursors.Cross;
}
if (!draw) return;
LocalMousePosition = pictureBox1.PointToClient(Cursor.Position);
int x = Math.Min(x_start, LocalMousePosition.X);
int y = Math.Min(y_start, LocalMousePosition.Y);
int width = Math.Max(x_start, LocalMousePosition.X) - Math.Min(x_start, LocalMousePosition.X);
int height = Math.Max(y_start, LocalMousePosition.Y) - Math.Min(y_start, LocalMousePosition.Y);
rect = new Rectangle(x, y, width, height);
xx = x;
yy = y;
ww = width;
hh = height;
Refresh();
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
//pictureBox1.Cursor = Cursors.Default;
draw = false;
rectang = new UserRect(rect);
rect = new Rectangle(e.X, e.Y, 0, 0);
rectang.SetPictureBox(this.pictureBox1);
}
else if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
pictureBox1.Cursor = Cursors.Default;
_tracking = false;
}
}
UserRect.cs
public void Draw(Graphics g)
{
g.DrawRectangle(new Pen(Color.Green), rect);
foreach (PosSizableRect pos in Enum.GetValues(typeof(PosSizableRect)))
{
g.DrawRectangle(new Pen(Color.Red), GetRect(pos));
}
}
public void SetPictureBox(PictureBox p)
{
this.mPictureBox = p;
mPictureBox.MouseDown += new MouseEventHandler(mPictureBox_MouseDown);
mPictureBox.MouseUp += new MouseEventHandler(mPictureBox_MouseUp);
mPictureBox.MouseMove += new MouseEventHandler(mPictureBox_MouseMove);
mPictureBox.Paint += new PaintEventHandler(mPictureBox_Paint);
}
private void mPictureBox_Paint(object sender, PaintEventArgs e)
{
try
{
Draw(e.Graphics);
}
catch (Exception exp)
{
System.Console.WriteLine(exp.Message);
}
}
private void mPictureBox_MouseDown(object sender, MouseEventArgs e)
{
mIsClick = true;
nodeSelected = PosSizableRect.None;
nodeSelected = GetNodeSelectable(e.Location);
if (rect.Contains(new Point(e.X, e.Y)))
{
mMove = true;
}
oldX = e.X;
oldY = e.Y;
}
private void mPictureBox_MouseUp(object sender, MouseEventArgs e)
{
//MessageBox.Show(rect.ToString());
mIsClick = false;
mMove = false;
}
private void mPictureBox_MouseMove(object sender, MouseEventArgs e)
{
ChangeCursor(e.Location);
if (mIsClick == false)
{
return;
}
Rectangle backupRect = rect;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
switch (nodeSelected)
{
case PosSizableRect.LeftUp:
rect.X += e.X - oldX;
rect.Width -= e.X - oldX;
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
case PosSizableRect.LeftMiddle:
rect.X += e.X - oldX;
rect.Width -= e.X - oldX;
break;
case PosSizableRect.LeftBottom:
rect.Width -= e.X - oldX;
rect.X += e.X - oldX;
rect.Height += e.Y - oldY;
break;
case PosSizableRect.BottomMiddle:
rect.Height += e.Y - oldY;
break;
case PosSizableRect.RightUp:
rect.Width += e.X - oldX;
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
case PosSizableRect.RightBottom:
rect.Width += e.X - oldX;
rect.Height += e.Y - oldY;
break;
case PosSizableRect.RightMiddle:
rect.Width += e.X - oldX;
break;
case PosSizableRect.UpMiddle:
rect.Y += e.Y - oldY;
rect.Height -= e.Y - oldY;
break;
default:
if (mMove)
{
rect.X = rect.X + e.X - oldX;
rect.Y = rect.Y + e.Y - oldY;
}
break;
}
}
oldX = e.X;
oldY = e.Y;
if (rect.Width < 5 || rect.Height < 5)
{
rect = backupRect;
}
TestIfRectInsideArea();
mPictureBox.Invalidate();
}
Generally, I would split drawing graphics between _Paint event as you have it (for interactive drawing, such as selection box and mouse-move related stuff) and separate underlaying image.
There are several reasons for that, such as control over what you want to draw (imagine you want to draw only retangle 1, 3 and 5, if a some checkbox is not checked and then draw all of 1 to 6 if it is checked) and performance (with large amount of data).
You can do all of that in _Paint, but it will bloat. In contrast to that, you can split draw task into several functions, which is very handy for large drawing.
Very simplified example - VB.NET:
Dim UnderlayingImage as Image
UnderLayingImage = New Bitmap(Me.PictureBox1.Width, Me.Picturebox1.Height)
Dim g As Graphics = Graphics.FromImage(UnderLayingImage)
Dim bgBrush As SolidBrush = New SolidBrush(Color.LightSlateGray)
Dim bgBrushWhite As SolidBrush = New SolidBrush(Color.White)
Dim shPen As Pen = New Pen(Color.Black)
Dim rect As RectangleF = New RectangleF(50, 50, 100, 100)
g.FillRectangle(bgBrush, rect)
g.DrawRectangle(Pens.Black, Rectangle.Round(rect))
Me.PictureBoxDrawing.Image = UnderLayingImage
Translated to C#:
Image UnderlayingImage;
UnderLayingImage = new Bitmap(this.PictureBox1.Width, this.Picturebox1.Height);
Graphics g = Graphics.FromImage(UnderLayingImage);
SolidBrush bgBrush = new SolidBrush(Color.LightSlateGray);
SolidBrush bgBrushWhite = new SolidBrush(Color.White);
Pen shPen = new Pen(Color.Black);
RectangleF rect = new RectangleF(50, 50, 100, 100);
g.FillRectangle(bgBrush, rect);
g.DrawRectangle(Pens.Black, Rectangle.Round(rect));
this.PictureBoxDrawing.Image = UnderLayingImage;
And back to your question: This way you don't Clear your drawing, but you redraw it and in the process you decide what to include and what to ommit.
I need help drawing line on picture box.
I get coordinates for point2 and point2 on mouse click and I drew line between this two coordinates.
What I need to do is to take value for point1 and start drawing the line from that point1, and line should follow my cursor and when I click second time on picture box it should be drawn.
Any help would be appreciated.
This is what I have so far
// Points p1(x1,y1), p2(x2,y2)
private Point p1, p2;
List<Point> p1List = new List<Point>();
List<Point> p2List = new List<Point>();
int count = 0;
// Click 2 times on image to get coordinate values for p1 & p2
private void pbChooseDirection_MouseDown(object sender, MouseEventArgs e)
{
if(count/2 == 0)
{
pbChooseDirection.Image = drawingLineImage;
}
if (p1.X == 0)
{
p1.X = e.X;
p1.Y = e.Y;
count++;
}
else
{
p2.X = e.X;
p2.Y = e.Y;
count++;
p1List.Add(p1);
p2List.Add(p2);
Invalidate();
// Sets X to 0 and choose p1 again
p1.X = 0;
}
}
private void pbChooseDirection_Paint_1(object sender, PaintEventArgs e)
{
using (var p = new Pen(Color.Blue, 4))
{
for (int x = 0; x < p1List.Count; x++)
{
e.Graphics.DrawLine(p, p1List[x], p2List[x]);
}
}
}
Recently, I have been working on this graphing system in C#, and I am having problems with the coordinate system. As we all know, C# uses the top left corner as 0,0 coordinates. What I want to accomplish is to make 0 in the middle of the windows form.
Currently, this is what I have...
As you can see, 0,0 is on the top left, making the center of the graph 400. So is there a way to transform the coordinates into a proper mathematical graph coordinate?
I hope I was able to explain this situation well as my English is not very well.
public partial class Form1 : Form
{
public static int _wWidth;
public static int _wHeight;
int mouseX, mouseY;
Point _center = new Point(_wWidth / 2, _wHeight / 2);
public Form1()
{
InitializeComponent();
foreach (Control c in this.Controls)
{
c.MouseDown += ShowMouseDown;
}
this.MouseDown += (s, e) => { this.label3.Text = "{X: " + e.X + " Y:" + e.Y + "}"; mouseX = e.X; mouseY = e.Y; };
}
private void ShowMouseDown(object sender, MouseEventArgs e)
{
var x = e.X + ((Control)sender).Left;
var y = e.Y + ((Control)sender).Top;
this.label3.Text = x + " " + y;
}
public void Form1_Load(object sender, EventArgs e)
{
this.ClientSize = new Size(800, 800);
int windowWidth = this.ClientSize.Width;
int windowHeight = this.ClientSize.Height;
_wWidth = windowWidth;
_wHeight = windowHeight;
button1.Location = new Point(_wWidth - button1.Width,0);
//AllocConsole(); /***** Enable console for debugging *****/
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();
public void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
_drawPlain(e);
}
public void _drawPlain(PaintEventArgs e){
Graphics formGraphics = this.CreateGraphics();
for(int x = 0; x < _wHeight; x+=50)
{
e.Graphics.DrawLine(new Pen(Color.FromArgb(80, 75, 75)), new Point(0, x), new Point(_wWidth, x));
Console.ForegroundColor = ConsoleColor.Green; if (x == 20) { Console.Write("X - "); } Console.WriteLine(x);
e.Graphics.DrawString(x.ToString(), new Font("Arial", 10), new SolidBrush(Color.White), new Point(_wWidth/2,x));
}
for (int y = 0; y < _wWidth; y += 50)
{
e.Graphics.DrawLine(new Pen(Color.FromArgb(80, 75, 75)), new Point(y, 0), new Point(y, _wHeight));
Console.ForegroundColor = ConsoleColor.Red; if (y == 20) { Console.Write("Y - "); } Console.WriteLine(y);
int num = y;
e.Graphics.DrawString(num.ToString(), new Font("Arial", 10), new SolidBrush(Color.White), new Point(y, _wHeight/2));
}
e.Graphics.DrawLine(Pens.Green, new Point(0, _wHeight/2), new Point(_wWidth, _wHeight/2));
e.Graphics.DrawLine(Pens.DarkRed, new Point(_wWidth/2, 0), new Point(_wWidth/2, _wHeight));
//e.Graphics.DrawString("0", new Font("Arial", 10), new SolidBrush(Color.White), new Point(_wWidth / 2, _wHeight / 2));
//// Create pen.
//Pen blackPen = new Pen(Color.Black, 3);
//// Create points that define polygon.
//Point point1 = new Point(100, 200);
//Point point2 = new Point(300, 200);
//Point point3 = new Point(200, 50);
//Point[] curvePoints =
// {
// point1,
// point2,
// point3
// };
//// Draw polygon to screen.
//e.Graphics.DrawPolygon(blackPen, curvePoints);
}
public static int _yCellCount()
{
int _cell = 0;
for (int i = 0; i < 20; i++)
{
_cell++;
}
return _cell;
}
private void button1_Click(object sender, EventArgs e)
{
this.Refresh();
}
private void Form1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawLine(Pens.Yellow,new Point(mouseX,mouseY),new Point(_wWidth/2,400));
}
}
Continuation of thread: C# Invalidate troubles. I created the class but now I get an Error 2 Embedded statement cannot be a declaration or labeled statement. And I am trying to create the "Car" by Car aCar = new Car(50,100); that is where I am getting the error.
Thanks for the suggestions.
class Car
{
private Pen pen1 = new Pen(Color.Blue, 2F);
private Pen pen2 = new Pen(Color.Green, 2F);
int cost = 0;
int x, y;
Graphics g;
public Car(int x, int y)
{
this.x = x;
this.y = y;
}
public void printCar()
{
g.DrawEllipse(pen1, x, y, 30, 30);
g.DrawEllipse(pen1, x + 100, y, 30, 30);
g.DrawRectangle(pen2, x - 5, y + 50, 140, 50);
g.DrawLine(pen2, x + 15, y + 50, x + 30, y + 90);
g.DrawLine(pen2, x + 30, y + 90, x + 90, y + 90);
g.DrawLine(pen2, x + 90, y + 90, x + 110, y + 50);
// Create string to draw.
String drawString = "Price: " + (cost).ToString("C");
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(50, 95);
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawPoint);
}
public partial class Form1 : Form
{
private Pen pen1 = new Pen(Color.Blue, 2F);
private Pen pen2 = new Pen(Color.Green, 2F);
private double cost ;
private int days = 0;
private double air;
private double automatic;
int count;
int m = 50;
Car aCar = new Car(50, 60);
public Form1()
{
InitializeComponent();
days = int.Parse(textBox1.Text);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem.ToString() == "Van")
{
cost = 110;
label1.Text = "The Cost of van per day" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
else if (comboBox1.SelectedItem.ToString() == "Car")
{
cost = 85.20;
label1.Text = "The Cost of car per day" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
else
{
cost = 135;
label1.Text = "Van" + (cost).ToString("C");
textBox1.Text = "1";
textBox1.Focus();
}
}
private void button1_Click(object sender, EventArgs e)
{
count++;
button1.Text = "Move";
pictureBox1.Invalidate();
if(count == 2)
button1.Text = "Reset";
if (count == 3)
{
textBox1.Text = "0";
count = 0;
comboBox1.Text = "select type of vehical";
checkBox1.Checked = false;
checkBox2.Checked = false;
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
if (count == 1)
aCar.printCar();
if (count == 2)
}
private void Form1_Load(object sender, EventArgs e)
{
}
The end of your picturebox1_Paint method opens an if statement but doesn't actually contain a body. That is illegal:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
if (count == 1)
aCar.printCar();
if (count == 2) // <-- This is illegal since the if statement is just dangling
}
You have to pass the Graphic object you are getting from the Paint event:
Public void printCar(Graphic g)
{
// etc, etc
}
So that when you call it:
aCar.printCar(e.Graphics);
I'm trying to make a canvas where you can zoom and pan. The panning works, but zooming at the mouse position won't work.
EDIT: This almost works. The center for zoom is slightly offset however...
This is the code for the zooming:
public partial class Form1 : Form
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1.0F;
public Form1()
{
InitializeComponent();
mouseDown = new PointF(0F, 0F);
this.panel1.Paint += new PaintEventHandler(panel1_Paint);
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = e.Graphics;
dc.SmoothingMode = SmoothingMode.AntiAlias;
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor);
Color lineColor = Color.FromArgb(200, 200, 200);
Pen linePen = new Pen(lineColor,1*zoomFactor);
dc.DrawLine(linePen, 100, 100, 200, 200);
textBox1.Text = newX.ToString();
textBox2.Text = newY.ToString();
}
private void panel1_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
mouseDown = mouse.Location;
mouseDown.X = mouseDown.X - newX;
mouseDown.Y = mouseDown.Y - newY;
}
}
private void panel1_MouseMove(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
Point mousePosNow = mouse.Location;
float deltaX = mousePosNow.X - mouseDown.X;
float deltaY = mousePosNow.Y - mouseDown.Y;
newX = deltaX;
newY = deltaY;
panel1.Invalidate();
}
}
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (e.Delta > 0)
{
if (zoomFactor + 0.2 < 10)
{
zoomFactor += 0.2F;
}
}
else if (e.Delta < 0)
{
if (zoomFactor - 0.2 > 0.2)
{
zoomFactor -= 0.2F;
}
}
float x = (mouse.Location.X - newX) * zoomFactor;
float y = (mouse.Location.Y - newY) * zoomFactor;
newX = mouse.Location.X - x;
newY = mouse.Location.Y - y;
panel1.Invalidate();
}
}
I finally figured it out, so here's the solution.
public partial class Form1 : Form
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1.0F;
public Form1()
{
InitializeComponent();
mouseDown = new PointF(0F, 0F);
this.panel1.Paint += new PaintEventHandler(panel1_Paint);
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown);
this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = e.Graphics;
dc.SmoothingMode = SmoothingMode.AntiAlias;
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend);
Color lineColor = Color.FromArgb(200, 200, 200);
Pen linePen = new Pen(lineColor,1*zoomFactor);
dc.DrawLine(linePen, 100, 100, 200, 100);
dc.DrawLine(linePen, 200, 100, 200, 200);
dc.DrawLine(linePen, 200, 200, 100, 200);
dc.DrawLine(linePen, 100, 200, 100, 100);
dc.DrawLine(linePen, 100, 100, 200, 200);
dc.DrawLine(linePen, 200, 100, 100, 200);
}
private void panel1_MouseDown(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
mouseDown = mouse.Location;
mouseDown.X = mouseDown.X - newX;
mouseDown.Y = mouseDown.Y - newY;
}
}
private void panel1_MouseMove(object sender, EventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
if (mouse.Button == MouseButtons.Right)
{
PointF mousePosNow = mouse.Location;
float deltaX = mousePosNow.X - mouseDown.X;
float deltaY = mousePosNow.Y - mouseDown.Y;
newX = deltaX;
newY = deltaY;
panel1.Invalidate();
}
}
protected override void OnMouseWheel(MouseEventArgs e)
{
MouseEventArgs mouse = e as MouseEventArgs;
PointF mP = mouse.Location;
if (e.Delta > 0)
{
if (zoomFactor >= 1 && zoomFactor <= 10)
{
zoomFactor += 1F;
newX = newX - ((mP.X - newX) / (zoomFactor - 1));
newY = newY - ((mP.Y - newY) / (zoomFactor - 1));
}
else if (zoomFactor == 0.5)
{
zoomFactor = zoomFactor * 2;
newX = newX - ((mP.X - newX) );
newY = newY - ((mP.Y - newY) );
}
else if (zoomFactor < 0.5)
{
zoomFactor = zoomFactor * 2;
newX = newX - ((mP.X - newX) );
newY = newY - ((mP.Y - newY) );
}
}
else if (e.Delta < 0)
{
if (zoomFactor >2)
{
zoomFactor -= 1F;
newX = newX + (((mP.X - newX)) / (zoomFactor+1 ));
newY = newY + (((mP.Y - newY)) / (zoomFactor+1));
}
else if (zoomFactor == 2) {
zoomFactor -= 1F;
newX = newX + ((mP.X - newX)/2);
newY = newY + ((mP.Y - newY)/2);
}else if(zoomFactor <= 1 && zoomFactor > 0.2)
{
zoomFactor = zoomFactor / 2;
newX = newX + ((mP.X - newX) / 2);
newY = newY + ((mP.Y - newY) / 2);
}
}
panel1.Invalidate();
}
}
Maybe your MousePosition is different from PanelPosition? I mean on is relative to the control and one relative to the screen?
Control.PointToScreen is your friend!