4

I have a need to calculate the height of a string given that I already know the width.

For example if have a string like "Curabitur semper ipsum semper nulla dictum, vel vulputate elit fringilla. Donec nec placerat purus, ut blandit lectus. Maecenas non molestie nulla. Class aptent taciti sociosqu."

I can use the following code to calculate the single-line width/height of that string.

using (Graphics gfx = Graphics.FromImage(new Bitmap(1, 1)))
{
    System.Drawing.Font f = new System.Drawing.Font(
        FontFamily.GenericSansSerif, 10, FontStyle.Regular);
    SizeF bounds = gfx.MeasureString(
        message, f, new PointF(0, 0), 
        new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
}

However, what I would like to do is calculate the height of that string if it were within a div of 200px, accounting for line wraps.

At first I thought it was a function of the width of the image used to derive the Graphics object.

using (Graphics gfx = Graphics.FromImage(new Bitmap(500, 200)))

That didn't help and got the same single-line dimensions.

Does anyone know of any other tricks to get this?

Andy Evans
  • 6,997
  • 18
  • 72
  • 118
  • Your problem definition is wrong. You are not looking for the height of a string rather of a control and its content. Knowing this, it should be obvious why `MeasureString` does not do the job. In fact, the more I consider this problem the more confused I am by the concept itself. What about padding? Why are you doing this to begin with? This problem has a lot of holes. – P.Brian.Mackey Dec 30 '13 at 17:10

2 Answers2

3

given that I already know the width

Then you'll of course have to tell MeasureString() about that width, note that you never did that in your code. MeasureString() has several overloads, you need to use one that takes a SizeF. Pass, say, new SizeF(500, int.MaxValue). The SizeF you'll get back will still have a Width of 500 but tells you the Height you are looking for.

Btw, only use DrawString/MeasureString when you draw to a printer. For text that's rendered to the screen you should favor TextRenderer instead.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

It sounds like you need to account for the WordBreak flag:

int h = 0;
using (Graphics g = CreateGraphics()) {
  using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) {
    h = TextRenderer.MeasureText(msg, f, new Size(200, 0), 
                                 TextFormatFlags.WordBreak).Height;
  }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225