How to reset paint area in OnPaint call - c#

I'm trying to create a semi-transparent user control button whose background opacity changes from 30% black to 70% black on mouseEnter. I can successfully paint the button 30% black but I can't go from 70% to 30%. It's as if every time OnPaint() is called, it paints over what was already there instead of starting from scratch. I use a subclassed Panel as the user control's background.
Here's my OnPaint method for the subclassed Panel:
Graphics g = e.Graphics;
Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
Brush brush = new SolidBrush(Color.FromArgb(Alpha, Color.Black)); // alpha is set by me
g.FillRectangle(brush, rect);
g.Dispose();
I've played with g.Clear() and g.Restore() but haven't had any luck. Any ideas?
Thanks!

I'm not sure how Windows handles transparency in that case. You should try invalidating the rectangle on the window below your window, if that window is repainted, the background might look just like you want.

I ended up solving this by swapping 30% opaque black and 70% opaque black assets for the background image. I also set the button's BackColor to Color.Transparent.

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?

Form with graphics distorts

In C# i have created a function to draw a triangle between a rich-textbox and a RectangleShape object.
below is what i wrote.
Graphics Pointer = this.CreateGraphics();
Pointer.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
Pointer.FillPolygon(new SolidBrush(Color.White), GetTriangle(this.FetchRectangle));
Pointer.Dispose();
The gettriangle() function returns an array of points(3 vertices of the triangle.) But when i try running the pgm, the form's background (which is set to black color) now takes a blurred and distorted background image of wat is shown in the computer screen.
How can i get the triangle image without distorting the form background?
this problem is cause due to http://en.wikipedia.org/wiki/Vertical_blanking_interval
The solution is double buffering. and waiting Vertical retrace. I couldn't find example how to do htis but this is the way to go
see:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/9f07dec1-1b04-419c-b604-44fd74027161/windows-forms-double-buffering-?forum=csharpgeneral

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.

Antialiased text on transparent bitmap

I'd like to draw antialiased text on a transparent bitmap and have the antialiasing drawn as alpha blended pixels. This way, I can draw the bitmap onto any color surface (or an image, for that matter) and the antialiasing still looks fine.
Here is a simplified sample showing the problem:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Bitmap bitmap = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.Empty);
g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));
e.Graphics.DrawImage(bitmap, new Point(0, 0));
}
And here is the result:
The ultimate goal of this is to use UpdateLayeredWindow to draw my transparent alpha blended window. I am creating a Conky-like application, and I'd like to be able to use ClearType rendering for text (this is easy without antialiasing, of course).
Currently, I grab the screen behind the form, draw that, and then draw my text. It looks good, but has to be updated and is slow to draw. Any other ideas to accomplish drawing text on the desktop would also be welcome.
Your text is displayed as it is because you have ClearType subpixel anti-aliasing mode enabled (which is the default on Vista and above). ClearType, by definintion, cannot play nice with alpha channel, since it blends colors, and thus isn't background-agnostic. So it ignores the alpha channel, and blends to black (which is your transparent color otherwise is). You need to enable plain grayscale anti-aliasing for the desired effect:
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
I'm not sure if it's really necessary, but if you want to do alpha-blending, you should specify a 32-bit image:
Bitmap bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Using your example, I was able to make the text look decent by adding a text rendering hint:
g.Clear(Color.Empty);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));
Is this doing what you want, or just hiding the problem?

How-to draw a circle on a changing background

There is a timer on the form and in its Tick event I've:
this.BackColor = ColorTranslator.FromHtml("#" + ColorCodesBack[_index]);
CurrentColor = ColorTranslator.FromHtml("#" + ColorCodesFore[_index]);
SolidBrush sb = new SolidBrush(CurrentColor);
g.FillEllipse(sb, this.Width/2 -200, this.Height/2 - 200, 200, 200);
g.DrawImage(b, 150, 150);
The problem is just background changes on every tick and I don't see a Circle on the form.
What you should do is put your code in the forms Paint event. That will cause your code to redraw ever time the form has to repaint. Like running your mouse over the form or moving the form. Also where are you declaring your graphic object? Because the only way it will be drawn on your form is if you do:
Graphics g = this.CreateGraphics();
If you use the paint event you won't even need a timer object.
You should combine this code with the same tick event that is changing the backgroud. Otherwise you effectively have a race condition as to which "tick" will be fired first. Combining them will solve that problem.
The suggestion to update the background and the foreground at the same time is solid.
If you cannot control this, perhaps you could add a transparent control to your window on top of the background, and draw onto the transparent control? That way you would always be above in the Z-Order. This would also reduce your need to redraw regularly.

Categories