Multi-line Graphics.MeasureString implementation on .Net CF
If you have ever tried to build a dynamic UI for a .Net Compact Framework application, probably you’ve had to build adjustable multi-line labels or text-boxes. It’s hard to solve because the only supported overload for Graphics.MeasureString on .Net CF is:
public SizeF MeasureString ( string text, Font font )
When you need to resize or position the controls dynamically in runtime, it’s very important to know what should be the size, particularly the height of the multi-line label or multi-line text-box. It’s the same problem if you’re building a new custom control with a complex layout and you need to measure a potential multi-line string.
Having only this overload on .Net CF, we cannot get a multi-line string size because it calculates just the size of a single-line string. If the string is longer than the string, it gets a big SizeF result but as a single-line text.
The only solution here is to implement our own multi-line MeasureString method.
To solve the problem, we’ll use the native API DrawText. It will calculate the size of the text according with the uFormat parameter and using the graphics (device context) selected font.
[DllImport(“coredll.dll”)]
static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, int wFormat);
static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, int wFormat);
Additionally, if the control if a text-box, we should use the DT_EDITCONTROL flag and add extra 6 pixels (3 pixels at top and 3 pixels at bottom) to the calculated size.
Remember, if you have an empty string, you’ll probably need to force one-line size for your controls.