Clever Techniques for Determing Dimensions of Multi-Line Label?

G

Guest

Long ago I developed a simple algorithm for calculating how much space is
required to display a multi-line label in a limited width. It seemed to be
working okay but then my testing revealed a flaw when trying to display the
following string with an MS Sans Serif 8 point font in a 208 pixel width
space:

"A $50-million investment in cycling infrastructure - the largest history of
the province"

Using the Graphics "MeasureString" function it determined that 2 lines were
necessary to display this text. But unfortunately the longer words forced a
word-wrap sooner than usual. So the string ended up being displayed like
this:

A $50-million investment in cycling
infrastructure - the largest history of the
province


As you can see, this is 3 lines, not 2. I realize I could overcompensate
the height required but then this will add an excessive vertical margin in
many cases. So I'm wondering if anyone has come up with a superior, accurate
approach to this problem?
 
M

Mohammad Shalabi

is it ok with you to use fixed width fonts? at least you do not need any
calcualtions.

thank you.
 
G

Guest

Mohammad,

Actually, using fixed-width fonts would NOT solve the problem because the
words will typically wrap sooner than one expects.

In any case, I've done more research and found some code which I modified
for my own purposes. I'll post it here, as it may help others in the future:

public static int MeasureLabelHeight(string text, Font font, int maxWid)
{
Form form1 = new Form(); // Necessary to access
'CreateGraphics' below
Graphics g = form1.CreateGraphics(); // Create a Graphics object
for the Control

System.Drawing.StringFormat format = new System.Drawing.StringFormat ();
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0,
maxWid, 10000);
System.Drawing.CharacterRange[] ranges = {new
System.Drawing.CharacterRange(0, text.Length)};
System.Drawing.Region[] regions = new System.Drawing.Region[1];

format.SetMeasurableCharacterRanges(ranges);

regions = g.MeasureCharacterRanges (text, font, rect, format);
rect = regions[0].GetBounds(g);

return (int)(rect.Bottom + 1.0F);
}
 
H

Helge Jensen

Robert said:
Using the Graphics "MeasureString" function it determined that 2 lines were
necessary to display this text. But unfortunately the longer words forced a
word-wrap sooner than usual. So the string ended up being displayed like
this:

Why are you determining the number of lines? MeasureString returns the
area needed.

Is this using SizeF MeasureString(string text, Font font, SizeF
layoutAread, StringFormat format)?

Try using the following code:

Label l = ...;
SizeF area = new SizeF(
l.ClientRectangle.Width, float.PositiveInfinity);
/* l.Format, but Label does not expose Format */
StringFormat format = StringFormat.GenericTypographic;

SizeF needed = graphics.MeasureString(
l.Text, l.font, area, format);
int borders = l.Height - l.ClientRectangle.Height;
l.Height = (int)(Math.Ceiling(needed.Height) + borders);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top