Change the Graphics properties of form Controls before Painting - c#

I have a windows form with several controls, e.g. labels and buttons. When the form is painted, in the Paint event handler, I can use the PaintEventArgs e to:
private void Form_Paint(object sender, PaintEventArgs e)
{
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
SolidBrush brush = new SolidBrush(Color.Black);
e.Graphics.DrawString("Test String", font, brush, 100, 100);
}
This way I can create a string using Graphics.DrawString() that conforms to the properties I set such as TextRenderingHint.
How can I change the Graphics properties for all the controls on the form, the labels and buttons etc, so that when they are painted/rendered they conform to the Graphics properties as I would like them to?
Specifically - I want to change the TextRenderingHint for controls on the form. I'd be equally happy if doing this for the Form itself including all controls was possible.

How can I change the Graphics properties for all the controls on the form, the labels and buttons etc, so that when they are painted/rendered they conform to the Graphics properties as I would like them to?
You can't.
As Hans has said in the comments, the built-in controls for Winforms are mostly just thin wrappers around existing native Windows control classes. They will render using the current user settings, which are global for all applications.
Even if they weren't, there's the other problem that the Graphics instance being used is new for every Paint event, and each window-based control (i.e. most of them) gets a Graphics instance corresponding to the native HDC for that control's window's WM_PAINT event. There's no "global" Graphics instance that you could change, and which then would be reused for every Paint event.

Related

how to draw rectangle by selecting four coordinate points by user in C# windows form and display the coordinate points in text box

In my c# windows form application I am trying to draw a rectangle by getting the coordinates from the user through 4 mouse click events in the windows form, one for each point.
Here is what I've tried so far.
private void Form1_Click(object sender, EventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
Pen pen = new Pen(Color.Black, 2);
Brush brush = new SolidBrush(this.BackColor);
g.FillRectangle(brush, this.Bounds); // redraws background
g.DrawRectangle(pen,textBox1.Text,textBox2.Text,textBox3.Text,textBox4.Text);
pen.Dispose();
brush.Dispose();
}
}
Your first mistake is drawing in a Click handler. Don't use CreateGraphics. Anything you draw with that is volatile and unlikely to play well.
What you should do is collect the points you want to draw when the Click event fires. Add a handler for the form's Paint event and do your drawing there. The event args will provide a Graphics object for you to use.
A separate method for calculating the rectangle might also be useful to keep that work out of the Paint handler.

GDI+ drawing becomes corrupted when ClientSize changes

I need to draw a circle with the size of the entire form. I have made a Form1 with the following Paint event handler:
private void Form1_Paint(object sender, PaintEventArgs e)
{
SolidBrush myBrush = new SolidBrush(Color.Black);
e.Graphics.FillEllipse(myBrush, 0, 0, this.ClientSize.Width, this.ClientSize.Height);
}
The problem is that when you change the size of the form or maximize it the drawing becomes corrupted. Please help me how to avoid this problem. Sorry I haven't found an appropriate topic on StackOverflow.
Painting for container controls like Form was optimized, they only redraw the part of the window that was revealed by the resize. In other words, if the user drags the right or bottom edge then there's no repaint at all when the window is made smaller. A small repaint if it is made bigger, only the part of the window to became visible.
This is normally very appropriate since they don't have much reason to completely repaint themselves, they only draw their background. This matters in particular when the user resizes the window by dragging a corner, that can generate a storm of repaint requests. And if repainting is slow then that gets to be very visible, moving the mouse makes the motion "stutter", flicker can be noticeable as well.
But you care, you need to completely redraw the ellipse since you use the ClientSize property in your paint event handler.
Whether or not this optimization is turned on is determined by a style flag for the control, as Sriram pointed out. Turning this off is so common that Winforms exposed the style flag through a simple property to make it easier to change it:
public Form1() {
InitializeComponent();
this.ResizeRedraw = true;
this.DoubleBuffered = true;
}
Note the DoubleBuffered property, another example of a convenience property that actually changed ControlStyles. You want this turned on to suppress the flicker your window exhibits. Caused by first drawing the background, which erases your ellipse, then repainting the ellipse.
There's another pretty serious problem in your code, SolidBrush is a disposable class. Disposing objects is optional, but skipping this for System.Drawing objects is quite unwise. If you resize your window frequently enough, 10000 times, then your program will crash. That sounds like a lot, but it is not when you set ResizeRedraw to true since that generates a lot of repaints. Only the garbage collector can keep you out of trouble, it won't in a simple program like this. Fix:
protected override void OnPaint(PaintEventArgs e) {
using (var brush = new SolidBrush(this.ForeColor)) {
e.Graphics.FillEllipse(brush, 0, 0, this.ClientSize.Width, this.ClientSize.Height);
}
base.OnPaint(e);
}
Btw, do not optimize this by keeping the brush around as recommended in another post. Creating a brush is very cheap, takes about a microsecond. But is far too expensive to keep around, it is allocated on a heap that's shared by all programs that run on the desktop. A limited resource, that heap is small and programs start failing badly when the that heap is out of storage.
You'll have to enable ResizeRedraw. Add the following to your constructor.
this.SetStyle(ControlStyles.ResizeRedraw, true);
On Forms Resize event paste this ;
this.Refresh();
this will redraw the form and fire the Form1.Paint event.
That occurs because only part of the form's area gets invalidated when the size changes. What you need to do is handle the SizeChanged event and call the form's Refresh method.
Call Graphics.Clear(); before drawing to clear the old graphics and avoid creating redundant brushes.Put the code for the Brush creation outside the block
SolidBrush myBrush = new SolidBrush(Color.Black);
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear();
e.Graphics.FillEllipse(myBrush, 0, 0, this.ClientSize.Width, this.ClientSize.Height);
}

Drawing to a brush

I have made a control which inherits TextBox, and I'm trying to give a notebook grid:
I already have the code that will specify where to draw the lines including all of the grids features, but I'm not sure what to draw it to.
I've Googled a lot and searched for a brush that will let me have the same interface as a DrawingContext (so I could call drawingContext.DrawLine() etc.), or something familiar, but I couldn't find any!
So how can I achieve to get my grid background?
P.S I can't create a static bmp file and load it, because the grid color and spacing would most certainly change
You could try using DrawingVisual to get your DrawingContext then create a VisualBrush to assign to your Background. Something like this.
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
dc.DrawLine( new Pen(Brushes.Red,5),new Point(0,0),new Point(50,50));
dc.Close();
VisualBrush vb = new VisualBrush(dv);
textBox1.Background = vb;
You can intercept the Paint event for your control. You get a PaintEventArgs argument, which includes a ClipRectangle and a Graphics object.
Check out Control.Paint Event.
Once you have your Graphics object, you can call DrawLine and FillRectangle on it directly.
You're looking to make a custom-drawn control. You'll want to override the OnPaint method of your control class and draw the background in that method. Here's an example on how to do it: http://msdn.microsoft.com/en-us/library/b818z6z6(v=vs.90).aspx
To draw your background, grab the drawing context and draw your background after first calling the base OnPaint method:
protected override void OnPaint(PaintEventArgs pe)
{
// Call the OnPaint method of the base class.
base.OnPaint(pe);
// Declare and instantiate a new pen.
System.Drawing.Pen myPen = new System.Drawing.Pen(Color.Aqua);
// Draw an aqua rectangle in the rectangle represented by the control.
pe.Graphics.DrawRectangle(myPen, new Rectangle(this.Location, this.Size));
}
EDIT:
Since you're using WPF, you can take a look here to see a full example on custom designs: WPF .NET 3.5 Drawing Customized Controls and Custom UI Elements

Movable Rectangle or Label

I am writing a program in Visual C# 2010 that has several icons on the form. When the mouse is placed over the icon (which is just an image) I want the icon to b highlighted via a border around the icon. In visual basic i can make a transparent rectangle with a colored border and position it over the icon. In C#, i can do the same however until i call invalidate multiple borders appear. The problem with calling invalidate is that my program is doing something in the background every second so the border keeps flashing (re-drawing).
Anyone got any ideas how i can implement this?
You didn’t say how you draw the border but from your description you are creating a graphics context for this. Don’t do this, it’s wrong. Instead, draw inside the Paint element of either the control or the its parent container.
The Paint event handler could look as follows:
private void yourControl_Paint(object sender, PaintEventArgs e)
{
if (! HasFocus(yourControl))
return;
Graphics g = e.Graphics;
using (Pen p = new Pen(Color.FromArgb(128, 0, 0, 128)))
g.DrawRectangle(p, 0, 0, yourControl.Width -1, yourControl.Height - 1);
}
This uses a hypothetical HasFocus method to determine whether this control should have a focus rectangle.
By the way, this is identical in VB and C#.

Simple rectangle box

How do put rectangular box around few controls on my winform? (i dont want the grouping thing).
If you don't want to use a GroupBox, you can put your controls in a Panel and set its BorderStyle property to BorderStyle.FixedSingle or BorderStyle.Fixed3D.
What's wrong with the GroupBox control? Grouping together a related set of controls is exactly what it's intended for. Your users have seen it in every other application they use, and throughout the Windows shell. They're much more likely to recognize what it means than your own custom-drawn rectangle. Deviating from standard platform conventions is rarely a good idea. I strongly recommend using the GroupBox control, even if it's not exactly the perfect look that you had in mind.
That being said, it's certainly possible to draw your own box around a group of controls on a form. To do so, you'll need to override your form's OnPaint method and write some code to draw a rectangle. Doing it this way gives you complete control over the color of your box, as well as the line thickness.
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Call the base class
base.OnPaint(e);
// Create your drawing pen
using (Pen p = new Pen(SystemColors.WindowText, 2.0))
{
// Calculate the position and dimensions of the box
Rectangle rect = new Rectangle(10, 10, 30, 30);
// Draw the rectangle
e.Graphics.DrawRectangle(p, rect);
}
}
The only thing you'll need to add is the code that calculates the dimensions of your rectangle, relative to the controls you want it to surround. Use the Location property of each control to get this information.
You can put your controls into a panel and set its BorderStyle from None to FixedSingle - it is the easiest way
http://msdn.microsoft.com/en-us/library/cyh3c8h8.aspx
Pen pen = new Pen(Color.FromArgb(255, 0, 0, 0));
e.Graphics.DrawLine(pen, 20, 10, 300, 100);
You can draw lines on a windows form this way. This would hook into the Paint method where e is PaintEventArgs

Categories

Resources