Correlating Windows forms textbox text width to GDI width

1.4k Views Asked by At

I'm drawing the text from a textbox using GDI; however, I'm trying to create my textbox such that it reflects the same amount of space that I am drawing to in GDI. So, for some X amount of width in GDI, I would like for the length of the string in the textbox to not be able to exceed this width.

To draw the string in GDI, I'm using the following:

Font font = new Font("Lucidia Console", 8, GraphicsUnit.Point);
StringFormat sf = (StringFormat)StringFormat.GenericTypographic.Clone();
g.DrawString(textFromTextbox, font, Brush, layoutRect, sf);

As for the textbox, I measure the string as characters are entered:

Font font = new Font("Lucidia Console", 8, GraphicsUnit.Point);
Size lineSize = TextRenderer.MeasureText(textbox.Text, font);
Size charSize = TextRenderer.MeasureText(e.KeyChar.ToString(), font);

if( charSize + lineSize > MAX_LINE_SIZE )
 //Other stuff;

I have the textbox itself using Lucidia Console 8pt as the font as well.

So, then the trouble becomes making a textbox of X width that's the same width as the width I'm drawing to in GDI.

I've run into all kinds of discussions about glyphs, em-size/pixel ratios, and other topics but with little resolve.

Any ideas?

2

There are 2 best solutions below

4
On

You could use the MeasureString method, which you'll find on your System.Drawing.Graphics instance.

0
On

g.DrawString uses GDI+ to draw the text on the screen.

TextRenderer.MeasureText uses GDI.

They are 2 different text rendering models so you will not get the desired results.

There is a Graphics.MeasureString method which is compatible with Graphics.DrawString but I have never gotten it to behave consistently. It might be good enough for your need though, it's worth a try.

Also, there was an article on CodeProject a while back where they drew text onto a bitmap and took a measurement off the bitmap in order to get the exact sizes. I don't remember the specifics but it shouldn't be hard to find. The article was about creating a textbox like control in .net only code.

Your other alternative is to use TextRenderer.DrawText to render the text. That actually does work and matches up nicely with TextRenderer.MeasureText. If you are doing a lot of measurements though it can be kind of slow.