Highlight selected custom control with C# WinForms - c#

I have created a custom control (the control is used for drag and drop) and I want to add focus and selected events to the control. Both need to be visually distinct. So I plan to implement a windows style for both of these events. For focus I have the control drawing a solid and a dotted line around the control using the following code in the Paint event.
if (Image != null)
{
if (ContainsFocus)
{
// Draw a dotted line inside the client rectangle
Rectangle insideRectangle = ClientRectangle;
insideRectangle.Inflate(-2, -2);
insideRectangle.Width--;
insideRectangle.Height--;
Pen p = new Pen(Color.Black, 1);
p.DashStyle = DashStyle.Dot;
g.DrawRectangle(p, insideRectangle);
// Draw a solid line on the edge of the client rectangle
Rectangle outsideRectangle = ClientRectangle;
outsideRectangle.Width--;
outsideRectangle.Height--;
p.DashStyle = DashStyle.Solid;
g.DrawRectangle(p, outsideRectangle);
Color transparentLightBlue = Color.FromArgb(100, Color.LightBlue);
Brush solidBrush = new SolidBrush(transparentLightBlue);
g.FillRectangle(solidBrush, ClientRectangle);
}
}
For the Focus event I want just the image to be highlighted (similar to windows explorer). My first attempt at this was to add the following code.
Color transparentLightBlue = Color.FromArgb(100, Color.LightBlue);
Brush solidBrush = new SolidBrush(transparentLightBlue);
g.FillRectangle(solidBrush, ClientRectangle);
This works filling in the rectangle however I would like to just highlight the image itself instead of the entire rectangle. I've had the idea of using two different images, however the image is supplied to me and I'm not storing them.
So my question: How is the best way to get just the image of the control that has focus to highlight?
Thank you in advance!

since your image is not transparent you could overlay it with a transparent highlight color. something similar to this.

Related

Undraw rectangle on an image

I have a custom control that displays an image. I'm using a custom control because I've implemented zooming functionality and scrollbars.
I'm draw a rectangle on the image by doing:
if (drawRect)
{
var g = Graphics.FromImage(Image);
g.DrawRectangle(Pens.Red, rect);
}
The drawing of the rectangle is toggled by a button. However, when I toggle off, the rectangle it's still being drawn on the image.
I'm assuming that once something is drawn on the image's surface, it stays there.
Is there a way to "undraw" something or do I need to implement a second "transparent" image that will act as an overlay?

Use picturebox as a canvas and draw text

I want to use a PictureBox as a canvas and draw some text on it and save.
I wrote this piece of code but I'm not sure if im doing this the correct way:
Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(b);
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height)); // i used this code to make the background color white
g.DrawString("some text", new Font("Times New Roman", 20), new SolidBrush(Color.Red), new PointF(10, 10));
pictureBox1.Image = b;
This code works well but when I want to change the background color of the image I have to redraw the text.
Is there a way to change the background color without having to redraw the text?
Writing a Paint program is a lot of fun, but you need to plan ahead for all or most of the features you want.
So far you have these:
A background you can change
A way to modify an image by drawing text on it
The need to save it all to a file
Here are a few more things you will need:
Other tools than just text, like lines, rectangles etc..
A choice of colors and pens with widths
A way to undo one or more steps
Here are few thing that are nice to have:
A way to help with drawing and positioning with the mouse
Other type backgrounds like a canvas or pergament paper
The ability to draw with some level of tranparency
A redo feature (*)
Rotation and scaling (***)
Levels (*****)
Some things are harder (*) or a lot harder (***) than others, but all get hard when you decide to patch them on too late..
Do read this post (starting at 'actually') about PictureBoxes, which explain how it is the ideal choice for a Paint program.
Your original piece of code and your question have these problems:
You seem to think that repeating anything, like redrawing the text is wrong. It is not. Windows redraws huge numbers of things all the time..
You have mixed two of the tasks which really should be separate.
You have not parametrizied anything, most notably the drawing of the text should use several variables:
Font
Brush
Position
the text itself
The same will be true once you draw lines or rectangles..
So here are the hints how do get it right:
Use the BackgroundColor and/or the BackgroundImage of the Picturebox to dynamically change the background!
Collect all things to draw in a List<someDrawActionclass>
Combine all drawings by drawing it into he Picturebox's Image
Use the Paint event to draw supporting things like the temporary rectangle or line while moving the mouse. On MouseUp you add it to the list..
So, coming to the end, let's fix your code..:
You set the backgound with a function like this:
void setBackground(Color col, string paperFile)
{
if (paperFile == "") pictureBox1.BackColor = col;
else pictureBox1.BackgroundImage = Image.FromFile(paperFile);
}
you can call it like this: setBackground(Color.White, "");
To draw a piece of text into the Image of the PictureBox, first make sure you have one:
void newCanvas()
{
Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
pictureBox1.Image = bmp;
}
Now you can write a function to write text. You really should not hard-code any of the settings, let alone the text! This is just a quick and very dirty example..:
void drawText()
{
using (Font font = new Font("Arial", 24f))
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
{
// no anti-aliasing, please
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
G.DrawString("Hello World", font, Brushes.Orange, 123f, 234f);
}
pictureBox1.Invalidate();
}
See here and here for a few remarks on how to create a drawAction class to store all the things your drawing is made up from..!
The last point is how to save all layers of the PictureBox:
void saveImage(string filename)
{
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save("yourFileName.png", ImageFormat.Png);
}
}

Drawing rectangle on uEye Camera c#

I am creating a application which displays a live view from a uEye camera in c# using visual studio. I have displayed the camera view in a picturebox.
I am wanting the user to type in a width and height they would like, once they have done this it will display this rectangle on the picturebox which has the camera view in.
I am using the following code...
Pen p = new Pen(Color.Red, 1);
Rectangle rect = new Rectangle(10, 10, Convert.ToInt32(width), Convert.ToInt32(height));
DisplayWindow.CreateGraphics().DrawRectangle(p, rect);
This draws the rectangle on the picture box but for only a second, then it disappears. Anyone know why this is?
Thanks guys
You will need to implement something like this; what happens is async drawing, resulting in strange behaviour.
DisplayWindow.Paint += (o, e) =>
{
e.Graphics.DrawRectangle(p, rect);
};
//To force redraw, just call
DisplayWindow.Invalidate();

Unexpected results from Graphics.FillRectangle()

I'm trying to make a little 15x15 playing grid, and drawing the solid outline rectangles side-by-side is working just fine, however when I try to call FillRectangle() to fill the aforementioned cells the results are .. Not quite what I expected.. I think it's easier if I just show you..
Here's the code
//Draw grid now since InitGrid() is done
using (Graphics formGraphics = this.CreateGraphics())
{
Pen pen = new Pen(Color.Black);
SolidBrush brush = new SolidBrush(Color.Beige);
int y = new int();
List<Rectangle> rect = new List<Rectangle>();
foreach (Cell cell in pGrid.cells)
{
rect.Add(new Rectangle(cell.Point.X, cell.Point.Y, 18, 18));
formGraphics.DrawRectangle(pen, rect[y]);
formGraphics.FillRectangle(brush, rect[y++]);
}
}
Also an extra question, since I am using a using code block do I still have to call Dispose() on the Pen and Graphics?
The differences in the "covered area" are caused by DrawRectangle using a Pen which has a thickness of 1px, and 0.5px of that is added to the outer edges of the rectangle, and then rounded "to the bottom-right". These bottom-right borders are then overwritten by the next cell's FillRectangle.
You could use a border thickness of 2, which would cause the border to be 2 pixels larger than the filled area, and thus appear 1px thick on each side.
Pen pen = new Pen(Color.Black, 2);
This only works if there is actual space between the cells to show the borders in. If there is no room for the borders you'll have to either shrink your cell size or grow the grid itself.
Another solution (since you mention the outlines are fine) is to first call FillRectangle and then DrawRectangle.
Also a using around the pen and brush won't hurt. Note that you can also use the static Pens.Black (unless you're going for the solution of a 2px thick border) and Brushes.Beige.

how to draw fixed string on pictureBox using C#?

I have to draw some text on pictureBox image (Gray scale image). I got some codes. its working but its moving with the image while panning and zooming, and it disappear while changing the window level.
rect = pictureBox1.ClientRectangle;
Graphics g = Graphics.FromImage(bmp);
SolidBrush brush = new SolidBrush(Color.Green);
Font f = new Font("Arial", 15);
g.DrawString("Murugesan", f, brush, start);
I want the text in the permanent location and it never disappear while changing the window level. Anybody there to help me.
You should draw it on PictureBox OnPaint event and use e.Graphics.
Probably you wouldn't have artifacts you mentioned if you used:
Graphics g = pictureBox.CreateGraphics();
But paint on event is still better than that.

Categories