Get rid of label margins
-
Tony_P wrote:
I can't use DrawString because I need to know the exact length of the text
That's what MeasureString is for.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008Alright I've just found this in the meantime. Thank you for your time!
-
Tony_P wrote:
I can't use DrawString because I need to know the exact length of the text
That's what MeasureString is for.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007, 2008this is what I came up with:
public class EnhancedLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush fore = new SolidBrush(this.ForeColor);
Brush back = new SolidBrush(this.BackColor);SizeF s = g.MeasureString(this.Text, this.Font); this.Width = (int)s.Width; this.Height = (int)s.Height; g.FillRectangle(back, this.Left, this.Top, this.Width, this.Height); g.DrawString(this.Text, this.Font, fore, this.Location); } }
-
this is what I came up with:
public class EnhancedLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush fore = new SolidBrush(this.ForeColor);
Brush back = new SolidBrush(this.BackColor);SizeF s = g.MeasureString(this.Text, this.Font); this.Width = (int)s.Width; this.Height = (int)s.Height; g.FillRectangle(back, this.Left, this.Top, this.Width, this.Height); g.DrawString(this.Text, this.Font, fore, this.Location); } }
And a version 2.0, much better ;o
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush fore = new SolidBrush(this.ForeColor);
Brush back = new SolidBrush(this.BackColor);g.FillRectangle(back, this.Location.X, this.Location.Y, this.Width, this.Height); g.DrawString(this.Text, this.Font, fore, Point.Empty); } protected override void OnTextChanged(EventArgs e) { Graphics g = System.Drawing.Graphics.FromHwnd(this.Handle); SizeF s = g.MeasureString(this.Text, this.Font); this.Width = (int)s.Width; this.Height = (int)s.Height; base.OnTextChanged(e); }
-
And a version 2.0, much better ;o
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush fore = new SolidBrush(this.ForeColor);
Brush back = new SolidBrush(this.BackColor);g.FillRectangle(back, this.Location.X, this.Location.Y, this.Width, this.Height); g.DrawString(this.Text, this.Font, fore, Point.Empty); } protected override void OnTextChanged(EventArgs e) { Graphics g = System.Drawing.Graphics.FromHwnd(this.Handle); SizeF s = g.MeasureString(this.Text, this.Font); this.Width = (int)s.Width; this.Height = (int)s.Height; base.OnTextChanged(e); }
Just a couple of points - You should dispose of your brushes, or better still put them in using blocks.
using (Brush back = new SolidBrush(ForeColor))
{
e.Graphics.FillRectangle(back, Location.X, Location.Y, Width, Height);
}
using (Brush fore = new SolidBrush(BackColor))
{
e.Graphics.DrawString(Text, Font, fore, Point.Empty);
}You can use the Size struct's static Round method to convert the SizeF
Size = Size.Round(s);
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) -
Just a couple of points - You should dispose of your brushes, or better still put them in using blocks.
using (Brush back = new SolidBrush(ForeColor))
{
e.Graphics.FillRectangle(back, Location.X, Location.Y, Width, Height);
}
using (Brush fore = new SolidBrush(BackColor))
{
e.Graphics.DrawString(Text, Font, fore, Point.Empty);
}You can use the Size struct's static Round method to convert the SizeF
Size = Size.Round(s);
Dave
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)Right, thank you for the tips. I used the brushes without even checking if it was a disposable object. Shame on me.
-
Right, thank you for the tips. I used the brushes without even checking if it was a disposable object. Shame on me.
Hi, the most expensive one, the one you really should dispose of, is the result of Graphics.FromHwnd() for the brushes, you might consider keeping them in a class member, rather than creating and disposing them all the time. creating a Graphics, as you do, is something I avoid even at modest cost; so I am not in favor of your 2.0 solution; instead I would do everything in OnPaint, possibly do MeasureString inside a test on text changed. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Fixturized forever. :confused:
-
Hi, the most expensive one, the one you really should dispose of, is the result of Graphics.FromHwnd() for the brushes, you might consider keeping them in a class member, rather than creating and disposing them all the time. creating a Graphics, as you do, is something I avoid even at modest cost; so I am not in favor of your 2.0 solution; instead I would do everything in OnPaint, possibly do MeasureString inside a test on text changed. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Fixturized forever. :confused:
Well the problem is that I need the width/height of the label without painting it, so I can't do everything in the paint event. The best way is probably to store the brushes, for sure. Can I store the Graphics.FromHwnd() the same way or can the value of Graphics.FromHwnd() change?
-
Well the problem is that I need the width/height of the label without painting it, so I can't do everything in the paint event. The best way is probably to store the brushes, for sure. Can I store the Graphics.FromHwnd() the same way or can the value of Graphics.FromHwnd() change?
Tony_P wrote:
I need the width/height of the label without painting it
Huh? if you need it inside OnPaint only, then do the MeasureString in OnPaint just before you use DrawString. if you need its result outside OnPaint, I would try and execute OnPaint once before you need the sizes. Keeping a Graphics does not feel right; for one it is an expensive object, and it contains many things that may be different each time you get a graphics; e.g. every time you move ab object over a Form, the Form may get Paint events with varying clip regions in the Graphics object. Also the user might change the resolution of the screen, and whatever more. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Fixturized forever. :confused:
-
Hi, the most expensive one, the one you really should dispose of, is the result of Graphics.FromHwnd() for the brushes, you might consider keeping them in a class member, rather than creating and disposing them all the time. creating a Graphics, as you do, is something I avoid even at modest cost; so I am not in favor of your 2.0 solution; instead I would do everything in OnPaint, possibly do MeasureString inside a test on text changed. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Fixturized forever. :confused:
Why don't you just write a function that does something like this:
class BlahBlah
{
SizeF m_textSize;public SizeF MeasureText(string text) { (using Graphics graphics = Graphics.FromHwnd(this)) { m\_textSize = graphics.MeasureString(text, someFont); } return m\_textSize; }
}
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
Why don't you just write a function that does something like this:
class BlahBlah
{
SizeF m_textSize;public SizeF MeasureText(string text) { (using Graphics graphics = Graphics.FromHwnd(this)) { m\_textSize = graphics.MeasureString(text, someFont); } return m\_textSize; }
}
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001I will do such things only if I see no reasonable alternative; I try and avoid creating a new Graphics as much as I can. In OnPaint the Graphics is for free, so why not take advantage of that one? In the few 100K lines of C# code I have at hand, I found only two instances of Graphics.FromHwnd; I do use Graphics.FromImage of course when drawing onto a Bitmap, there simply is no alternative there. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Fixturized forever. :confused: