I am having trouble drawing graphics on a simple form. My code compiles and runs, but the intended red box does not show up.
I am using the full .NET Framework 4 in Visual Studio 2010.
What is going wrong, and how can it be fixed?
private void Form1_Load(object sender, EventArgs e)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Red, 5);
Rectangle myRectangle = new Rectangle(20, 20, 250, 200);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
EDIT: Working But Slow Code
void BatteryPaint(object sender, EventArgs e)
{
TabPage page = (TabPage)sender;
if (!controlsSetup)
{
populateBatteryTab(page);
controlsSetup = true;
}
//Create the items
Rectangle busBar = new Rectangle();
Rectangle batPack = new Rectangle();
Rectangle pack1Outline = new Rectangle();
Rectangle pack2Outline = new Rectangle();
Rectangle pack3Outline = new Rectangle();
Rectangle pack4Outline = new Rectangle();
Color GreenZone = Color.FromArgb(150, 0, 255, 0);
Color YellowZone = Color.FromArgb(150, 255, 255, 0);
Color RedZone = Color.FromArgb(150, 255, 0, 0);
Color greyZone = Color.FromArgb(200, 200, 200, 200);
Graphics graphicControl = page.CreateGraphics();
SolidBrush busBarBrush = new SolidBrush(Color.Peru);
SolidBrush GreenBrush = new SolidBrush(GreenZone);
SolidBrush GreyBrush = new SolidBrush(greyZone);
Pen packPen = new Pen(Color.LightGray, (float)8);
Point busBarTop = new Point(page.Width / 64, page.Height / 32);
Point busBarBottom = new Point(busBarTop.X, busBarTop.Y + page.Height / 6);
//change the properties
//Bus Bar Top
busBar.Width = page.Width*153 / 640;
busBar.Height = page.Height / 64;
busBar.Location = busBarTop;
graphicControl.FillRectangle(busBarBrush, busBar);
//Bus Bar Bottom
busBar.Location = busBarBottom;
graphicControl.FillRectangle(busBarBrush, busBar);
//Pack 1
batPack.Width = page.Width / 20;
batPack.Height = (busBarBottom.Y + busBar.Height) - busBarTop.Y;
batPack.Location = new Point(busBarTop.X + page.Width / packSpacingMultiplier, busBarTop.Y);
pack1Outline.Width = batOutlineWidth;
graphicControl.FillRectangle(GreenBrush, batPack);
pack1Outline.Height = (3 * (Battery.Width + page.Width / batSpacingMultiplier) + page.Width / batSpacingMultiplier);
pack1Outline.Location = new Point(BatPack1.X - (page.Width / batSpacingMultiplier), BatPack1.Y - (page.Width / batSpacingMultiplier));
for(int numBats = 0; numBats < 30; numBats++)
{
Battery.Location = new Point(BatPack1.X + ((numBats % 10) * (Battery.Width + page.Width / batSpacingMultiplier)), BatPack1.Y + ((numBats / 10) * (Battery.Width + page.Width / batSpacingMultiplier)));
graphicControl.FillEllipse(new SolidBrush(BatteryZone(0.00)), Battery);
}
//Pack 2
batPack.Location = new Point(batPack.Location.X + batPack.Width + page.Width / packSpacingMultiplier, batPack.Location.Y);
graphicControl.FillRectangle(GreenBrush, batPack);
pack2Outline.Width = batOutlineWidth;
pack2Outline.Height = (3 * (Battery.Width + page.Width / batSpacingMultiplier) + page.Width / batSpacingMultiplier);
pack2Outline.Location = new Point(BatPack2.X - (page.Width / batSpacingMultiplier), BatPack2.Y - (page.Width / batSpacingMultiplier));
for(int numBats = 0; numBats < 30; numBats++)
{
Battery.Location = new Point(BatPack2.X + ((numBats % 10) * (Battery.Width + page.Width / batSpacingMultiplier)), BatPack2.Y + ((numBats / 10) * (Battery.Width + page.Width / batSpacingMultiplier)));
graphicControl.FillEllipse(new SolidBrush(BatteryZone(0.00)), Battery);
}
//Pack 3
batPack.Location = new Point(batPack.Location.X + batPack.Width + page.Width / packSpacingMultiplier, batPack.Location.Y);
graphicControl.FillRectangle(GreenBrush, batPack);
pack3Outline.Width = batOutlineWidth;
pack3Outline.Height = (3 * (Battery.Width + page.Width / batSpacingMultiplier) + page.Width / batSpacingMultiplier);
pack3Outline.Location = new Point(BatPack3.X - (page.Width / batSpacingMultiplier), BatPack3.Y - (page.Width / batSpacingMultiplier));
for(int numBats = 0; numBats < 30; numBats++)
{
Battery.Location = new Point(BatPack3.X + ((numBats % 10) * (Battery.Width + page.Width / batSpacingMultiplier)), BatPack3.Y + ((numBats / 10) * (Battery.Width + page.Width / batSpacingMultiplier)));
graphicControl.FillEllipse(new SolidBrush(BatteryZone(0.00)), Battery);
}
//Pack 4
batPack.Location = new Point(batPack.Location.X + batPack.Width + page.Width / packSpacingMultiplier, batPack.Location.Y);
graphicControl.FillRectangle(GreyBrush, batPack);
pack4Outline.Width = batOutlineWidth;
pack4Outline.Height = (3 * (Battery.Width + page.Width / batSpacingMultiplier) + page.Width / batSpacingMultiplier);
pack4Outline.Location = new Point(BatPack4.X - (page.Width / batSpacingMultiplier), BatPack4.Y - (page.Width / batSpacingMultiplier));
for(int numBats = 0; numBats < 30; numBats++)
{
Battery.Location = new Point(BatPack4.X + ((numBats % 10) * (Battery.Width + page.Width / batSpacingMultiplier)), BatPack4.Y + ((numBats / 10) * (Battery.Width + page.Width / batSpacingMultiplier)));
graphicControl.FillEllipse(new SolidBrush(BatteryZone(0.00)), Battery);
}
//add the controls
graphicControl.DrawRectangle(packPen, pack1Outline);
graphicControl.DrawRectangle(packPen, pack2Outline);
graphicControl.DrawRectangle(packPen, pack3Outline);
graphicControl.DrawRectangle(packPen, pack4Outline);
}
You shouldn't do your drawing in the Load event, which is fired before your form is even displayed for the first time. The window is repainted when it is displayed, which clears the graphics you've drawn. If you want a persistent rectangle, handle the Paint event instead:
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics graphicsObj = e.Graphics;
Pen myPen = new Pen(System.Drawing.Color.Red, 5);
Rectangle myRectangle = new Rectangle(20, 20, 250, 200);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
If you don't want a persistent rectangle (highly doubtful, but still possible), try handling the Shown event instead of the Load event.
If the graphics displayed will be updated frequently (e.g. in a game), make sure to set DoubleBuffered to true and override OnPaint instead of handling an event:
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen myPen = new Pen(Color.Red, 5);
g.DrawRectangle(myPen, 20, 20, 250, 200);
}
Related
I've been drawn multiple rectangles on the picturebox image.I want to resize all that rectangles using mouse events. Can anyone help me out regarding this?
public List<rectangle> listRec = new List<rectangle>();
Graphics g;
//private Graphics g;
Point startPos;
Point currentPos;
bool drawing;
Rectangle r1;
Rectangle rect = new Rectangle();
private Rectangle getRectangle()
{
r1 = new Rectangle(
Math.Min(startPos.X, currentPos.X),
Math.Min(startPos.Y, currentPos.Y),
Math.Abs(startPos.X - currentPos.X),
Math.Abs(startPos.Y - currentPos.Y));
return r1;
}
private void button1_Click(object sender, EventArgs e)
{
String data;
Font font = new Font("Arial", 14);
arg1 = Convert.ToInt32(textBox1.Text);
arg2 = Convert.ToInt32(textBox2.Text);
Rectangle rect = new Rectangle();
rect.Size = new Size(40, 65);
for (int x = 0; x < arg1; x++)
{
// rect.X = x * rect.Width;
rect.X = x * (rect.Width + 30) + 73;
for (int y = 0; y < arg2; y++)
{
rect.Y = y * (rect.Height + 35) + 38;
listRec.Add(rect);
data = rect.ToString();
TextWriter txt = new StreamWriter("E:\\B1Pockets.txt", true);
txt.WriteLine(data);
txt.Close();
// MessageBox.Show(rect.ToString());
}
}
foreach (Rectangle rec in listRec)
{
g = pictureBox1.CreateGraphics();
Pen p = new Pen(Color.Red, 3);
g.DrawRectangle(p, rec);
g.DrawString("p1", font, new SolidBrush(Color.Yellow), (rect.Width + 30), 35);
g.DrawString("p2", font, new SolidBrush(Color.Yellow), (rect.Width + 40) + 60, 35);
g.DrawString("p3", font, new SolidBrush(Color.Yellow), (rect.Width + 40) + 130, 35);
g.DrawString("p4", font, new SolidBrush(Color.Yellow), (rect.Width + 30), (rect.Height + 30) + 40);
g.DrawString("p5", font, new SolidBrush(Color.Yellow), (rect.Width + 40) + 60, (rect.Height + 30) + 40);
g.DrawString("p6", font, new SolidBrush(Color.Yellow), (rect.Width + 40) + 130, (rect.Height + 30) + 40);
}
}
I've tried this code to my application.I drawn rectangles in 2*3 manner.and also draw a big rectangle above it.In short my picturebox containing many rectangles and i want to add resizing options for all the rectangles in c#
I want my custom circular progress bar in WinForm. But the result doesnt fit to what I think. How can I draw the shape as the same in this picture?. I uploaded two image to be clear in my problem.
My code to do this:
void Form1_Paint(object sender, PaintEventArgs e)
{
int angle = 120;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
Rectangle outerRect = new Rectangle(50, 50, 100, 100);
Rectangle innerRect = new Rectangle(70, 70, 60, 60);
int innerRadius = innerRect.Width / 2;
int outerRadius = outerRect.Width / 2;
Point innerCenter = new Point(innerRect.X + innerRadius, innerRect.Y + innerRadius);
Point outerCenter = new Point(outerRect.X + outerRadius, outerRect.Y + outerRadius);
GraphicsPath outerCircle = new GraphicsPath();
outerCircle.AddEllipse(outerRect);
GraphicsPath innerCircle = new GraphicsPath();
innerCircle.AddEllipse(innerRect);
GraphicsPath progPath = new GraphicsPath();
Point p1 = new Point(outerRect.X + outerRadius, outerRect.Y);
Point p2 = new Point(innerRect.X + innerRadius, innerRect.Y);
Point inner = new Point((int)(innerRadius * Math.Cos(angle * Math.PI / 180) + innerCenter.X),
(int)(innerRadius * Math.Sin(angle * Math.PI / 180) + innerCenter.Y));
Point outer = new Point((int)(outerRadius * Math.Cos(angle * Math.PI / 180) + outerCenter.X),
(int)(outerRadius * Math.Sin(angle * Math.PI / 180) + outerCenter.Y));
progPath.AddLine(p1, p2);
progPath.AddArc(innerRect, -90, angle);
progPath.AddLine(inner, outer);
progPath.AddArc(outerRect, angle - 90,-angle);
progPath.Widen(Pens.Black);
e.Graphics.DrawPath(Pens.Black, progPath);
}
You can create a GraphicsPath, then add 2 arcs to the path using AddArc method:
Outer arc from start angle 270 and sweep angle 120 degree.
Inner arc in opposite direction, from start angle 270 + 120 and sweep angle -120 degree
Then close the path using GraphicsPath.CloseFigure.
This way the you will have a thick arc as path.
You can fill the path, using Graphics.FillPath method. And also you can draw the borders using GraphicsPath.DrawPath method.
Result
Code
private void Form1_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
var center = new Point(100, 100);
var innerR = 30;
var thickness = 20;
var startAngle = 270;
var arcLength = 120;
var outerR = innerR + thickness;
var outerRect = new Rectangle
(center.X - outerR, center.Y - outerR, 2 * outerR, 2 * outerR);
var innerRect = new Rectangle
(center.X - innerR, center.Y - innerR, 2 * innerR, 2 * innerR);
using (var p = new GraphicsPath())
{
p.AddArc(outerRect, startAngle, arcLength);
p.AddArc(innerRect, startAngle + arcLength, -arcLength);
p.CloseFigure();
e.Graphics.FillPath(Brushes.Green, p);
e.Graphics.DrawPath(Pens.Black, p);
}
}
I have two pictureboxes: One in the background with an image in it (picturebox1) and another one,(pic1) were i want to paint something (this background should be transparent.--> pic1.BackColor = Color.Transparent;)
It look like that:
Everything works great except the font. why does it have a black border?
My code looks like that:
private void InBitmapZeichnen()
{
Graphics g1 = Graphics.FromImage(bmp12);
g1.PageUnit = GraphicsUnit.Pixel;
//g1.InterpolationMode = InterpolationMode.HighQualityBilinear;
Font f = new Font("Verdana", 8f);
Font f1 = new Font("Verdana", 8f);
Font f2 = new Font("Verdana", 10, System.Drawing.FontStyle.Bold);
Brush b = new SolidBrush(Color.YellowGreen);
Brush b1 = new SolidBrush(Color.YellowGreen);
Pen PenRaster = new Pen(Color.Black, 0.1f);
if (mnuRaster.Checked == true)
{
float j = Rohrdurchmesser / (float)(trk.Value + 2);
//g1.SmoothingMode = SmoothingMode.HighSpeed;
for (int i = pic1.Width / (trk.Value + 2); i <= pic1.Width - pic1.Width / (trk.Value + 2); i += pic1.Width / (trk.Value + 2))
{
PointF PRaster1 = new PointF(i, 0);
PointF PRaster2 = new PointF(i, pic1.Bottom);
PointF PRaster3 = new PointF(0, i+4);
PointF PRaster4 = new PointF(pic1.Right, i+4);
g1.DrawString((j).ToString("0") + " mm", f, b, new PointF(i + 5, 5));
g1.DrawString((j).ToString("0") + " mm", f, b, new PointF(5, i + 5));
g1.DrawLine(PenRaster, PRaster1, PRaster2);
g1.DrawLine(PenRaster, PRaster3, PRaster4);
j += Rohrdurchmesser / (float)(trk.Value + 2);
}
}
}
When I select a color for backcolor it works fine:
Try use GraphicsPath if you want to draw text on trasparent background:
private void InBitmapZeichnen()
{
Graphics g1 = Graphics.FromImage(bmp12);
g1.PageUnit = GraphicsUnit.Pixel;
g1.SmoothingMode = SmoothingMode.AntiAlias;
//g1.InterpolationMode = InterpolationMode.HighQualityBilinear;
Font f = new Font("Verdana", 8f);
Font f1 = new Font("Verdana", 8f);
Font f2 = new Font("Verdana", 10, System.Drawing.FontStyle.Bold);
Brush b = new SolidBrush(Color.YellowGreen);
Brush b1 = new SolidBrush(Color.YellowGreen);
Pen PenRaster = new Pen(Color.Black, 0.1f);
if (mnuRaster.Checked == true)
{
float j = Rohrdurchmesser / (float)(trk.Value + 2);
//g1.SmoothingMode = SmoothingMode.HighSpeed;
for (int i = pic1.Width / (trk.Value + 2); i <= pic1.Width - pic1.Width / (trk.Value + 2); i += pic1.Width / (trk.Value + 2))
{
PointF PRaster1 = new PointF(i, 0);
PointF PRaster2 = new PointF(i, pic1.Bottom);
PointF PRaster3 = new PointF(0, i + 4);
PointF PRaster4 = new PointF(pic1.Right, i + 4);
using (var path = new GraphicsPath())
{
path.AddString((j).ToString("0") + " mm", f.FontFamily, (int)f.Style, f.Size, new Point(i + 5, 5), null);
path.AddString((j).ToString("0") + " mm", f.FontFamily, (int)f.Style, f.Size, new Point(5, i + 5), null);
g1.FillPath(b, path);
}
//g1.DrawString((j).ToString("0") + " mm", f, b, new PointF(i + 5, 5));
//g1.DrawString((j).ToString("0") + " mm", f, b, new PointF(5, i + 5));
g1.DrawLine(PenRaster, PRaster1, PRaster2);
g1.DrawLine(PenRaster, PRaster3, PRaster4);
j += Rohrdurchmesser / (float)(trk.Value + 2);
}
}
}
As you can see instead of DrawString i used FillPath.
I think need to clear Back Color before you start drawing on picture box.
Graphics g1 = Graphics.FromImage(bmp12);
// add clear
g1.Clear(BackColor);
So try this statement in your code...!!!
just wondering if i can draw line on selection index for combobox .
ss: http://oi59.tinypic.com/lzdxj.jpg
referring to screenshot above:
number1 -|> i want to achieve
number2 -|> current output that i have for combobox using this code:
sample code:
void ComboBox1_DrawItem(object sender, ListBoxDrawItemEventArgs e)
{
float[] location = new float[4];
Pen pen = new Pen(Color.FromArgb(255, 255, 255, 255), 2f);
if (e.Item.ToString() == "2")
{
var q = e.Bounds;
pen = new Pen(Color.FromArgb(255, 255, 255, 255), 2f);
//Rectangle r = e.Bounds;
var x = ComboBox1.Size.Width - 13;
location[0] = 10;
location[1] = (e.Bounds.Y / 2) + ((e.Bounds.Y + e.Bounds.Height) / 2) + .5f;
location[2] = x;
location[3] = (e.Bounds.Y / 2) + ((e.Bounds.Y + e.Bounds.Height) / 2) + .5f;
e.Graphics.DrawLine(pen, location[0], location[1], location[2], location[3]);
e.Handled = true;
}
if (e.State != DrawItemState.Selected) return;
e.Cache.FillRectangle(Color.FromArgb(83, 83, 83), e.Bounds);
e.Graphics.DrawLine(pen, location[0], location[1], location[2], location[3]);
e.Handled = true;
}
how can i achieve it?
Note:
Im using DevExpress ComboBoxEdit
My code is drawing a circle then a line from the middle of the circle to the radius size of the circle and the line is moving by 1 angle.
Now i want to make that the line will leave some trail/trace after it like a radar effect.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
anglecounter += 1;
double x = pictureBox1.Size.Width / 2 + 256 *Math.Cos(anglecounter * Math.PI / 180);
double y = pictureBox1.Size.Height / 2 +256 * Math.Sin(anglecounter * Math.PI / 180);
CloudEnteringAlert.Paint(e.Graphics, factor, distance);
e.Graphics.DrawLine(
new Pen(Color.Red, 2f),
new Point(pictureBox1.Size.Width / 2, pictureBox1.Size.Height/2),
new Point((int)x, (int)y));
e.Graphics.DrawEllipse(
new Pen(Color.Red, 2f),
0, 0, pictureBox1.Size.Width, pictureBox1.Size.Height);
}
How can I do this?
EDIT**
This is what i did now in the top of the form i added:
PointF _pt = new PointF(0F, 0F);
PointF _pt2 = new PointF(1F, 1F);
PointF _pt3 = new PointF(2F, 2F);
Color _lineColor = Color.FromArgb(0, 255, 0);
private double anglecounter1;
Then the paint event is now look like this:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
anglecounter += 1;
anglecounter1 += 0.5;
double x = pictureBox1.Size.Width / 2 + 256 *Math.Cos(anglecounter * Math.PI / 180);
double y = pictureBox1.Size.Height / 2 +256 * Math.Sin(anglecounter * Math.PI / 180);
double x1 = pictureBox1.Size.Width / 2 + 256 * Math.Cos(anglecounter1 * Math.PI / 180);
double y1 = pictureBox1.Size.Height / 2 + 256 * Math.Sin(anglecounter1 * Math.PI / 180);
CloudEnteringAlert.Paint(e.Graphics, factor, distance);
e.Graphics.DrawLine(
new Pen(Color.Red, 2f),
new Point(pictureBox1.Size.Width / 2, pictureBox1.Size.Height/2),
new Point((int)x, (int)y));
e.Graphics.DrawEllipse(
new Pen(Color.Red, 2f),
0, 0, pictureBox1.Size.Width, pictureBox1.Size.Height);
// create the fade path and gradient
GraphicsPath gp = new GraphicsPath(FillMode.Winding);
gp.AddLine(new PointF((float)(pictureBox1.Size.Width / 2), (float)(pictureBox1.Size.Height / 2)),new PointF( (float)x1,(float)y1));
gp.AddCurve(new PointF[] { _pt2, _pt3, _pt });
gp.AddLine(new PointF((float)x, (float)y), new PointF((float)(pictureBox1.Size.Width / 2), (float)(pictureBox1.Size.Height / 2)));
PathGradientBrush pgb = new PathGradientBrush(gp);
pgb.CenterPoint = new PointF((float)x1, (float)y1);
pgb.CenterColor = Color.FromArgb(128, _lineColor);
pgb.SurroundColors = new Color[] { Color.Empty };
// draw the fade path
e.Graphics.FillPath(pgb, gp);
}
But if im not wrong in this case the trail/trace is slower then the line is getting faster then it. Also the trail/trace is also behind the line but also in front of the line . Im not sure but thats what i see. So what is wrong ?
Another option is to not erase the image each time. Instead, draw a semi-transparent circle over the previous image:
// Initialize some dimensions
int x = pictureBox1.Bounds.X;
int y = pictureBox1.Bounds.Y;
int w = Math.Min(pictureBox1.Bounds.Width, pictureBox1.Bounds.Height);
int h = w; // Force square
int centerX = w / 2;
int centerY = h / 2;
float radius = w - centerX;
Graphics g = pictureBox1.CreateGraphics();
// First time draw a solid background then
// each successive time cover with semi-transparent background
Brush backGround = firstTime ? new SolidBrush(Color.FromArgb(255, 0, 0, 0)) : new SolidBrush(Color.FromArgb(10, 0, 0, 0));
firstTime = false;
g.FillEllipse(backGround, 0, 0, w, h);
float lineX = (float)(centerX + (radius * Math.Sin(anglecounter * (Math.PI / 180))));
float lineY = (float)(centerX + (radius * Math.Cos(anglecounter * (Math.PI / 180))));
anglecounter -= 1;
g.DrawLine(new Pen(Color.Green, 3), centerX, centerY, lineX, lineY);
g.DrawArc(new Pen(Color.Red, 4), new Rectangle(0, 0, w - 1, h - 1), 0, 360);
Produces this result: