FillRectangle over Child Controls Inside a FlowLayoutPanel - c#

I want to draw a rectangle on Mousedown for Mousearea Select on my panel:
private void flowLayoutPanel1_Paint_1(object sender, PaintEventArgs e)
{
if (mouseDown)
{
Brush brush = new SolidBrush(Color.DodgerBlue);
Graphics g = this.flowLayoutPanel1.CreateGraphics();
g.FillRectangle(brush, selection);
}
}
Selection here has the rect area on which Mouse has been dragged upon.
But if I put Form-Elements, like a Picturebox , on this panel,
my rectangle is behind this button.
But I want to render it in the front.
What can I do to solve this problem ?

Related

WinForms - How do I run a function with PaintEventArgs when the form is loaded?

I'm trying to understand the graphics, and in the Graphics.FromImage documentation, it has this as an example:
private void FromImageImage(PaintEventArgs e)
{
// Create image.
Image imageFile = Image.FromFile("SampImag.jpg");
// Create graphics object for alteration.
Graphics newGraphics = Graphics.FromImage(imageFile);
// Alter image.
newGraphics.FillRectangle(new SolidBrush(Color.Black), 100, 50, 100, 100);
// Draw image to screen.
e.Graphics.DrawImage(imageFile, new PointF(0.0F, 0.0F));
// Dispose of graphics object.
newGraphics.Dispose();
}
I'm new to C# and Windows Forms and am struggling to understand how this all fits together. How is this code run, say when the form first loads or when a button is pressed?
Maybe this will help. I have an example of both drawing on Paint events but also drawing on top of an existing Image. I created a form with two picture boxes. One for each case. pictureBox1 has an event handler for the .Paint event, while pictureBox2 is only drawn when a button is pressed.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
pictureBox1.BackColor=Color.Black;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// The code below will draw on the surface of pictureBox1
// It gets triggered automatically by Windows, or by
// calling .Invalidate() or .Refresh() on the picture box.
DrawGraphics(e.Graphics, pictureBox1.ClientRectangle);
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
// The code below will draw on an existing image shown in pictureBox2
var img = new Bitmap(pictureBox2.Image);
var g = Graphics.FromImage(img);
DrawGraphics(g, pictureBox2.ClientRectangle);
pictureBox2.Image=img;
}
void DrawGraphics(Graphics g, Rectangle target)
{
// draw a red rectangle around the moon
g.DrawRectangle(Pens.Red, 130, 69, 8, 8);
}
}
So when you launch the application a red rectangle appears on the left only, because the button hasn't been pressed yet.
and when the button is pressed, the red rectangle appears on top of the image displayed in pictureBox2.
Nothing dramatic, but it does the job. So depending on the mode of operation you need (user graphics, or image annotations) use the example code to understand how to do it.

Draw selection Area in WinForm Application

In my WinForm I need to draw selection area on the screen. User should be able to drag selected rectangle on corners or border to resize. As below:
I could draw the rectangle with solid brush.
How can I make it resizeable when dragging from border or corner?
private void panel1_MouseDown(object sender, MouseEventArgs e) {
using (Graphics g = this.panel1.CreateGraphics()) {
Pen pen = new Pen(Color.Black, 2);
Brush brush = new SolidBrush(this.panel1.BackColor);
g.FillRectangle(brush, this.panel1.Bounds);
g.DrawRectangle(pen, e.X, e.Y, 20, 20);
pen.Dispose();
brush.Dispose();
}
}
Instead of using MouseDown, I think you can use MouseMove.
At first, this event checks if left button is pressed:
if(e.Button == MouseButtons.Left)) {
//Check for the position of your mouse
}
Now you will put some ifstatement to be sure you will redraw your rectangle depending on your little resize boxes. Every if will recalculate the rectangle, erasing the old one and plotting the newest.
Hope this helps.

How to get all the pixel values inside a rectangle in C#

I'm developing a program to get all the pixels inside a rectangle. There is an image control and the user can click on a part inside it. When the user clicks on a particular location, a rectangle is drawn. I would like to get all the pixels inside that rectangle. I'm getting to draw the rectangle now. But i'm not able to get all the pixel values. Please find the code snippet for drawing the rectangle below.
private void panel1_Paint(object sender, PaintEventArgs e)
{
foreach (var rectKey in rectangles.Keys)
{
using (var pen = new Pen(rectKey)) //Create the pen used to draw the rectangle (using statement makes sure the pen is disposed)
{
//Draws all rectangles for the current color
//Note that we're using the Graphics object that is passed into the event handler.
e.Graphics.DrawRectangles(pen, rectangles[rectKey].ToArray());
}
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Color c = System.Drawing.Color.GreenYellow ; //Gets a color for which to draw the rectangle
//Adds the rectangle using the color as the key for the dictionary
if (!rectangles.ContainsKey(c))
{
rectangles.Add(c, new List<Rectangle>());
}
rectangles[c].Add(new Rectangle(e.Location.X - 12, e.Location.Y - 12, 25, 25)); //Adds the rectangle to the collection
}
//Make the panel repaint itself.
panel1.Refresh();// Directs to panel1_Paint() event
rectangles.Clear();
}
You would have to work with the Bitmap not the graphics object in this case.
Bitmap has a method to get pixels at a position
Bitmap bmp = Bitmap.FromFile("");
// Get the color of a pixel within myBitmap.
Color pixelColor = bmp.GetPixel(50, 50);
To read all pixels within a rectangle you could use the bmp.LockBits method.

How to keep graphics when resizing C# form

I am working on a program where I need to draw rectangle graphics onto the form itself, when I click the form. I created code to do this (below), but when I resize the form the rectangles are deleted.
How do I retain the drawn rectangles when the form is resized?
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
Graphics g = this.CreateGraphics();
Pen Haitham = new Pen(Color.Silver, 2);
g.FillRectangle(Haitham.Brush, new Rectangle(e.X, e.Y, 50, 50));
}
You could do this instead:
private List<Point> _points = new List<Point>();
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
foreach(Point point in _points)
{
using (Pen Haitham = new Pen(Color.Silver, 2))
{
e.Graphics.FillRectangle(Haitham.Brush, new Rectangle(point.X, point.Y, 50, 50));
}
}
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
_points.Add(new Point(e.X, e.Y));
Invalidate(); // could be optimized to invalidate only the future rectangle draw
}
In Windows with Winforms (or native Windows), you supposed to override OnPaint and do almost all your paint logic there.
Note with WPF, it would be different, you would compose a scene adding elements to it (here you would add a Rectangle shape to a Canvas for example).
You must do the "Graphics" things in the "Paint" event. Then you can see your rectangle always, because the event fires whenever windows needed to invalidate the paintings.
Cheers
I'm not too terribly familiar with graphics, but I am assuming that you would need to put all of your drawing objects into a container and have them redrawn when the form is sized. You might need to recall all of your paining objects in the sizeChanged event.

How to assign a click event handler to part of a drawn rectangle?

Imagine I use the .NET graphic classes to draw a rectangle.
How could I then assign an event so that if the user clicks a certain point, or a certain point range, something happens (a click event handler)?
I was reading CLR via C# and the event section, and I thought of this scenario from what I had read.
A code example of this would really improve my understanding of events in C#/.NET.
Thanks
You can assign Click event handler to control whose surface will be used to draw rectangle.
Here is a small example:
When you click on form inside of rectangle it will be drawn with red border when you click outside it will be drawn with black border.
public partial class Form1 : Form
{
private Rectangle rect;
private Pen pen = Pens.Black;
public Form1()
{
InitializeComponent();
rect = new Rectangle(10, 10, Width - 30, Height - 60);
Click += Form1_Click;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(pen, rect);
}
void Form1_Click(object sender, EventArgs e)
{
Point cursorPos = this.PointToClient(Cursor.Position);
if (rect.Contains(cursorPos))
{
pen = Pens.Red;
}
else
{
pen = Pens.Black;
}
Invalidate();
}
}
PointToClient method translates cursor coordinates to control-relative coordinates. I.e. if you cursor is at (screenX, screenY) position on the screen it can be at (formX, formY) position relatively to form's top-left corner. We need to call it to bring cursor position into coordinate system used by our rectangle.
Invalidate method makes control to redraw itself. In our case it triggers OnPaint event handler to redraw rectangle with a new border color.

Categories