User defined painting not visible - c#

I have a Windows Forms application with a GroupBox, and a PictureBox as background image, and several clickable OvalShapes from the PowerPack.
Now I need some labels for the OvalShapes, so I put a EventHandler on my GroupBox that on every repaint, the following should be drawn
this.groupBoxTest.Paint += new System.Windows.Forms.PaintEventHandler(this.groupBoxVirtualView_Paint);
private void groupBoxVirtualView_Paint(object sender, PaintEventArgs e)
{
Graphics g = groupBoxVirtualView.CreateGraphics();//e.Graphics;
g.DrawString("01", new Font("Arial", 12), new SolidBrush(Color.Black), 240, 115);
}
But the string 01 never gets drawn; all I see are the oval shapes that are at the same position - disabling them for testing purpose doesn't do it either.
What's happening to my string?
Any other way to label my PoweredOval?

You have to use
groupBoxVirtualView.Invalidate();
to repaint the groupBox!

The paint event should use the graphic object from the sender:
private void groupBoxVirtualView_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawString("01", new Font("Arial", 12), new SolidBrush(Color.Black), 240, 115);
}
Also, if there is a PictureBox inside the GroupBox, that control will not show any of the GroupBox paintings to come through the control. It will hide it.

Related

How to draw a frame the same as a System.Windows.Forms.TextBox

In WinForms how do I draw a frame the same as in a System.Windows.Forms.TextBox control?
I tried to use VisualStyleRenderer with the VisualStyleElement.TextBox.TextEdit.Normal parameter but it draws a strange gray line.
VisualStyleElement.Button.PushButton.Normal for a button works correctly.
It draws the face just as the button but for TextBox it draws a gray line border.
I used the following code:
private void panel1_Paint (object sender, PaintEventArgs e)
{
VisualStyleRenderer vsr = new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Normal);
vsr.DrawBackground (e.Graphics, new Rectangle (500, 12, 100, 20));
vsr = new VisualStyleRenderer (VisualStyleElement.Button.PushButton.Normal);
vsr.DrawBackground (e.Graphics, new Rectangle (500, 47, 100, 23));
}
Look at the screenshot.
On the left are Edit and Button controls.
On the right is what gets drawn by VisualStyleRenderer.DrawBackground

scrolling in a ScrollableControl: is there a .NET variant of MFC ViewPort?

I'm learning how to draw in Winforms. I've created a Form, with a panel with scrollbars. Upone Event Paint I draw an ellipse. This is fairly straightforward:
this.panel1.AutoScroll = true;
this.panel1.AutoScrollMinSize = = new System.Drawing.Size(500, 300);
private void OnPaint(object sender, PaintEventArgs e)
{
Rectangle ellipse = new Rectangle(Point.Empty, new Size(400, 400));
ellipse.Offset(this.panel1.AutoScrollPosition);
using (Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red))
{
e.Graphics.DrawEllipse(myPen, ellipse);
}
}
private void OnPanelScroll(object sender, ScrollEventArgs e)
{
this.panel1.Invalidate();
}
This works fine, but the complete image is redrawn when resizing or scrolling the panel.
A long time ago, in the time of MFC there was the notion of ViewPort / SetViewPortOrg / mapping modes / etc.. Scrolling and resizing did not require a recalculation of the complete image. Once you had drawn the image you didn't have to redraw as long as the complete image was not changed. All you had to do was move the viewport, or change the mapping mode
Does .NET have something similar that can do the scrolling for me? Maybe I should not draw on a panel, but on another subclass of a ScrollableControl?

Draw ellipse with PaintEventArgs

I have a simple Photoshop-made grid and i would like to use it as progress bar, i need to draw round ellipses from 1 to 100 (then probably about 100 times in x time).
If I use System.Graphic I have not persistent result.
Then I found the code to use the PaintEventArgs method by inserting instructions in the Paint Event of the form.
Unfortunately in my mind this is not a solution because I need to draw only when I need and only where I want.... in other word I need a simple Function able to draw desired ellipses when I need...
I tried also to override the OnPaint-base but I really don't understand how to use it and if may help to reach my goal.
Here some code:
With the paint event:
private void Main_Paint(object sender, PaintEventArgs e)
{
// Create pen.
Pen blackPen = new Pen(Color.Yellow, 3);
// Create rectangle for ellipse.
Rectangle rect = new Rectangle(355, 282, 9, 9);
e.Graphics.DrawEllipse(blackPen, rect);
}
With the Graphic mode:
private void lbl_help_Click(object sender, EventArgs e)
{
//SetStatus("BURNING PROCESS COMPLETED SUCCESSFULLY");
Graphics g = this.CreateGraphics();
// Create pen.
Pen blackPen = new Pen(Color.Yellow, 3);
// Create rectangle for ellipse.
Rectangle rect = new Rectangle(355, 282, 9, 9);
// Draw ellipse to screen.
g.DrawEllipse(blackPen, rect);
System.Threading.Thread.Sleep(3000);
}
And this one I found to override OnPaint(), but I really don't know how to use it, how to override the form-paint event or how to call it only when needed and passing values:
private void lbl_help_Click(object sender, EventArgs e)
{
//SetStatus("BURNING PROCESS COMPLETED SUCCESSFULLY",);
Graphics g = this.CreateGraphics();
// Create pen.
Pen blackPen = new Pen(Color.Yellow, 3);
// Create rectangle for ellipse.
Rectangle rect = new Rectangle(355, 282, 9, 9);
// Draw ellipse to screen.
g.DrawEllipse(blackPen, rect);
System.Threading.Thread.Sleep(3000);
}
Something other other:
I imagine if I use variables to store the percentage and call a paint-refresh of the form (maybe invalidate?) to update the result should work but I will lose any sort of animation, elsewhere I come-back to a non persistent state again... I need to use the grid as a progress bar, adding circles only at desired time, without losing the back drawings...
The grid I need to fill is very simple, here a screenshot:
Sry I should not post image for the reputation (i'm a new user!), here the link
EDIT:
I solved the smoothing problem (at least with the Graphic Mode):
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

Problem with CreateGraphics and drawing strings

The control below draws a string in a rectangle. On mouse move there is a hit test on the string rectangle, and the string is redrawn via CreateGraphics. The irritating problem is that the text is not drawn the same as in the Paint handler; it appears to be displaced by about 1 pixel, and the effect is like a bold font. How can I create a graphics object exactly like the one in the Paint handler so the text is drawn the same way? Ordinarily you would invalidate and redraw everything in the Paint event, but I have potentially hundreds of of other drawing items and only want to draw the string. Should I try to do any drawing outside of the Paint event or is this a mistake?
Example control:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test.TestModes
{
public partial class ExampleControl: UserControl
{
private const string testString = "0123456789";
private RectangleF stringRect = new RectangleF(10, 10, 100, 20);
public ExampleControl()
{
InitializeComponent();
}
private void ExampleControl_Paint(object sender, PaintEventArgs e)
{
Font font = new Font("Arial", 12, FontStyle.Regular);
e.Graphics.DrawString(testString, font, Brushes.Black, stringRect);
font.Dispose();
}
private void DrawString(bool hit)
{
Font font = new Font("Arial", 12, FontStyle.Regular);
using(Graphics g = CreateGraphics())
{
g.SetClip(ClientRectangle);
if(hit)
g.DrawString(testString, font, Brushes.Red, stringRect);
else
g.DrawString(testString, font, Brushes.Black, stringRect);
}
font.Dispose();
}
private void ExampleControl_MouseMove(object sender, MouseEventArgs e)
{
if(stringRect.Contains(e.Location))
DrawString(true);
else
DrawString(false);
}
private void button1_Click(object sender, EventArgs e)
{
Invalidate();
}
}
}
It is the CreateGraphics() call that is getting you in trouble, indirectly. The problem is anti-aliasing of the text. A normal painting cycle erases the background before drawing something on top. That doesn't happen in your case, your draw text on top of existing text. The side effect is that the pixels uses to create the aliasing get darker each time your draw. The end result is bold looking, and noticeably jagged text outlines.
The fix is easy: start with a clean slate before you draw:
using (Graphics g = CreateGraphics()) {
g.Clear(this.BackColor); <=== added
g.SetClip(ClientRectangle);
// etc..
}
You'll now also get to encounter a problem in drawing known as "flicker". It might not yet be that noticeable yet, but it will when you do more drawing. Flicker is suppressed with double-buffering. A feature supported by Windows Forms, but only if you use standard drawing techniques. In other words: no CreateGraphics().

How to draw text on picturebox?

I googled for "Drawing text on picturebox C#" ,but I couldnt find anything useful.Then I googled for "Drawing text on form C#" and I found some code,but it doesnt work the way I want it to work.
private void DrawText()
{
Graphics grf = this.CreateGraphics();
try
{
grf.Clear(Color.White);
using (Font myFont = new Font("Arial", 14))
{
grf.DrawString("Hello .NET Guide!", myFont, Brushes.Green, new PointF(2, 2));
}
}
finally
{
grf.Dispose();
}
}
When I call the function,the background color of the form becomes white(it's black by default).
My questions:
1:Will this work on a picturebox?
2:How to fix the problem?
You don't want that call to Clear() - that's why it's turning the background white, and it will cover up your picture.
You want to use the Paint event in the PictureBox. You get the graphics reference from e.Graphics, and then use the DrawString() that you have in your sample.
Here's a sample. Just add a picture box to your form, and add an event handler for the Paint event:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Font myFont = new Font("Arial", 14))
{
e.Graphics.DrawString("Hello .NET Guide!", myFont, Brushes.Green, new Point(2, 2));
}
}
(Note that you won't see the text at design time - you'll have to run the program for it to paint).

Categories

Resources