Always visible drawing on form - c#

I want to draw always visible cross over picturebox on winform. I know ho to use Graphics and it's method DrawLine. But problem is that, painted cross is hidden behind the picturebox. this textbox is continually refreshed and this cross should be always visible.
Do you have some solution for this?
Here is code:
Point picBoxLocation = pictureBox.Location;
Size picBoxSize = pictureBox.Size;
Pen myPen = new Pen(System.Drawing.Color.Red, 5);
Point left = new Point(picBoxLocation.X, picBoxSize.Height/2);
Point right = new Point(picBoxLocation.X+picBoxSize.Width, picBoxSize.Height / 2);
Point up = new Point((picBoxLocation.X + picBoxSize.Width) / 2, picBoxLocation.Y);
Point bottom = new Point((picBoxLocation.X + picBoxSize.Width) / 2, (picBoxLocation.Y+picBoxSize.Height)/2);
Graphics graphics = this.CreateGraphics();
graphics.DrawLine(myPen, left, right);
graphics.DrawLine(myPen, up, bottom);

Try to get Graphics object in OnPaint callback:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawLine(...);
}

Related

C# Cursor Position not in right place in forms

I'm trying to create a square that is located where the user clicks. I have pSize, pX, and pY as variables to represent the location and size of the square. But when I click on the form, the square is at least 70 pixels of in X and Y coordinates where the mouse clicked. I did (this is in the form click function):
pX = Cursor.Position.X;
pY = Cursor.Position.Y;
Graphics g = this.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Black);
g.FillRectangle(brush, pX, pY, pSize, pSize);
Here is a picture of what is happening:
The screenshot doesn't show my cursor but it is in the top left corner. I also noticed that every time I start the program, the amount the square is offset changes so this time it's relatively distant while next time it could be only about 25 pixels away in both axes.
Could someone tell me what I am doing wrong and/or what I can do about it? Thanks.
You're currently getting the Cursor position. Which is relative to the screen, which is why it is a different offset when you move the form around.
To get the position relative to your Form you need to use the Mouse Click position (sounds similar which is how this tricks people).
You need to make sure your Click event raises a MouseEventHandler:
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.DrawSquare);
Then you need to get the coordintaes from the event handler:
private void DrawSquare(object sender, MouseEventArgs e)
{
int pX = e.X;
int pY = e.Y;
int pSize = 10;
Graphics g = this.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Black);
g.FillRectangle(brush, pX, pY, pSize, pSize);
}
I think you don't need the cursor position, but the click position instead.
Try this:
private void Form2_MouseClick(object sender, MouseEventArgs e)
{
int pX = e.X;
int pY = e.Y;
Graphics g = this.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Black);
g.FillRectangle(brush, pX, pY, 10, 10);//Size just for testing purposes
}

Clear graphics/rectangle without changing colour?

I'm drawing a rectangle onto a Panel object (PanelArea) using the following code:
private void GenerateGraphic()
{
Graphics RandomArea = PanelArea.CreateGraphics();
RandomArea.Clear(Color.Beige);
SolidBrush Brush1 = new SolidBrush(Color.FromArgb(128,220,20,60));
Rectangle rect = new Rectangle();
//Offset is from the top left hand corner.
rect.X = 25;
rect.Y = 25;
rect.Width = 1;
rect.Height = 1;
rect.Inflate(XArea / 2, YArea / 2);
RandomArea.FillRectangle(Brush1, rect);
}
I'm setting the BackgroundImage of the Panel to a snippet of the screen.
I'd like to be able to keep the background image, whilst resetting the rectangle for it to be resized.
I need RandomArea.Clear(Color.Beige) to reset the graphics in order to remove the previous rectangle. The snag is though, is that this places the colour over the background image of the panel.
How can I clear the graphics area/rectangle each time, whilst still being able to view a background image for the Panel?

Winforms label drawing over a button with custom drawing

So I have this little app that has a button and a label. The button has a custom OnPaint methods to make it look unique. The label currently does not. However the label seems to be drawing inside the button for no apparent reason. Look at this:
For clarities sake I've disabled rendering the fill rectangle since it mostly covers the problem. Here's my button's OnPaint code:
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
Pen p = new Pen (Color.Black, 2);
Rectangle fillRect = new Rectangle (e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2);
Brush b;
if (MouseHovering)
{
b = new SolidBrush (Color.DarkSlateGray);
}
else
{
b = new SolidBrush (Color.Gray);
}
//g.FillRectangle (b, fillRect);
g.DrawRectangle (p, e.ClipRectangle);
//g.DrawString (Text, new Font ("Arial", 8), new SolidBrush (Color.Black), new Point (4, 4));
}
And here is the code that creates the label and button in the main form class:
label = new Label ();
label.Text = "Hello World";
label.Top = 15;
label.Left = 180;
label.AutoSize = true;
Controls.Add (label);
CButton b = new CButton ();
b.Text = "Click me for a new sentence";
b.AutoSize = true;
b.Top = 10; b.Left = 10;
Controls.Add (b);
The above is called in the constructor. And then when the button is pressed the label text is set like this:
label.Text = Specifier + " " + Verb + " a " + CommonNoun;
So what's happening here and how do I fix it? If you require any other code to understand the problem don't hesitate to ask.
There are some things missing. g.Clear(BackColor); will clear the contents of the buffer that the Graphics object is painting on.
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.Clear(BackColor);
g.SmoothingMode = SmoothingMode.HighQuality;
Pen p = new Pen (Color.Black, 2);
Rectangle fillRect = new Rectangle (e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2);
Brush b;
if (MouseHovering)
{
b = new SolidBrush (Color.DarkSlateGray);
}
else
{
b = new SolidBrush (Color.Gray);
}
//g.FillRectangle (b, fillRect);
g.DrawRectangle (p, e.ClipRectangle);
//g.DrawString (Text, new Font ("Arial", 8), new SolidBrush (Color.Black), new Point (4, 4));
b.Dispose(); //ADD THIS
p.Dispose(); //ADD THIS TOO
}
Also remember that its very important to dispose of any GDI resources that you are using. These might be .NET constructs, but they really are unmanaged objects in the background. Disposing them properly will prevent memory leaks and hard-to-understand crashes.
Also, you shouldn't be using the clip rectangle, use the actual bounds of the control.
The best option is to wrap them in using statements:
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
Color fillColor = MouseHovering ? Color.DarkSlateGray : Color.Gray;
using (Pen p = new Pen(Color.Black, 2))
using (Brush b = new SolidBrush(fillColor))
{
Rectangle fillRect = new Rectangle (0, 0, this.Width, this.Height);
g.DrawRectangle (p, e.ClipRectangle);
}
}
Using the using statement has the added benefit of if there is an exception inside the using, the objects will still be disposed correctly. The other option is to wrap them in a try..catch..finally, but unless you need to do something with the exception, this is a lot cleaner.

Drawing a rectangle over panel

I need to draw a rectangle into a panel. I dont know the color in advance, I get the color during runtime, I dont know how to set the color not to a fixed value, and second - when i try to draw the rectangle, it does nothing at all. Here is my code that should draw the rectangle (infact it does in another project, but thats just in a plain form, not into a panel)
Graphics g;
g = CreateGraphics();
Pen p;
Rectangle r;
p = new Pen(Brushes.Blue);
r = new Rectangle(1, 1, 578, 38);
g.DrawRectangle(p, r);`
So I need to replace (Brushes.Blue) with a variable and I need to draw the rectangle in a panel on its coordinates set in this code..
Construct your Pen using the Pen(Color) constructor instead of the Pen(Brush) one. Then you can define your color once you know it.
You should perform drawing in the Paint event of the panel. This event occurs whenever windows decides it's time to repaint the panel, and the PaintEventArgs contain a Graphics object you can draw the rectangle on.
The Brush is an abstract class, but you can use the SolidBrush object to create a custom colored brush at runtime:
int red = 255;
int green = 0;
int blue = 0;
Brush myBrush = new SolidBrush(Color.FromArgb(red, green, blue));
Here you are:
private Color _color; // save the color somewhere
private bool iKnowDaColor = false; // this will be set to true when we know the color
public Form1() {
InitializeComponents();
// on invalidate we want to be able to draw the rectangle
panel1.Paint += new PaintEventHandler(panel_Paint);
}
void panel_Paint(object sender, PaintEventArgs e) {
// if we know the color paint the rectangle
if(iKnowDaColor) {
e.Graphics.DrawRectangle(new Pen(_color),
1, 1, 578, 38);
}
}
And when you know the color:
_color = ...
iKnowDaColor = true;
// causes the panel to invalidate and our painting procedure to be called
panel.Invalidate();
I haven't tested this but should give you the basic idea.
put the following code in the appropriate place :
Graphics g = panel1.CreateGraphics();
int redInt=255, blueInt=255, greenInt=255; //255 is example, give it what u know
Pen p = new Pen(Color.FromArgb(redInt,blueInt,greenInt));
Rectangle r = new Rectangle(1, 1, 578, 38);
g.DrawRectangle(p, r);
and if you wanted to draw the rectangle somewhere else, say the form, you could do g = this.CreateGraphics.
I think that the better way of doing that is to extend the Panel class and add some custom OnPaint event logic.
public class PanelRect : Panel
{
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Graphics g = e.Graphics)
{
Rectangle rect = ClientRectangle;
rect.Location = new Point(20, 20); // specify rectangle relative position here (relative to parent container)
rect.Size = new Size(30, 30); // specify rectangle size here
using (Brush brush = new SolidBrush(Color.Aqua)) // specify color here and brush type here
{
g.FillRectangle(brush, rect);
}
}
}
}
P.S. This is not an advanced example, but might help you. You can move size, location and color etc to properties so you can easily change them from designer.
P.S. P.S. If you need a non-filled rectangle just use Pen object instead of Brush (you might also change the FillRectangle to something more suitable).

How can I use the Pen tool to draw a simple black line on a PictureBox's Image object?

I'm trying to draw a line that goes from middle top to bottom.
I know I have to use the Pen class to accomplish this.
private void RepaintPreview()
{
Pen blackPen = new Pen(Brushes.Black);
blackPen.Width = 1.0f;
blackPen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;
ptbTablePreview.Image.draw?
}
Basically, how can I draw this line on the image? Thank you.
I tried the following, and it works with me:
1- I set the image of the picturebox in design time
2- I handled the Paint event of the picturebox, and added the following code:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Pen p = new Pen(Color.Black, 2))
{
e.Graphics.DrawLine(p, new Point(pictureBox1.Width / 2, 0), new Point(pictureBox1.Width / 2, pictureBox1.Height));
}
}

Categories