Saturday, April 04, 2009

VB.Net Auto grow Textbox as text changes

I have several textboxes on a form that I would like them to grow as the user types text into them. Sometimes they will only put in a few words, other times it can be several lines of text. I expected this to be a very simple process but had a hard time finding a solution.

Several people did talk about using the TextBox.lines.count to figure out how tall to make the box. The problem with that is you must turn word wrap off for that to work. Sometimes you can do that. In my case, I needed the lines to wrap.

I did find references to Graphics.MeasurString(String,Font) as SizeF to figure out how long a string would be with a given font. I was about to overlook the effect different fonts and sizes would have had but it looks like this will solve both.

In the end, I took each line in the txt box. I calculated how many times each line would wrap and add that to my line count. Then used the Textbox.Font.Height to figure out how high each line would be. I also added 10 pixels to account for any padding at the top and bottom of the text box.

Here is the code I ended up with:

Dim numberOfLines As Integer = 0
Dim e As Graphics = Graphics.FromImage(New Bitmap(300, 300))
Dim StringSize As New SizeF
For Each item As String In tBox.Lines
StringSize = e.MeasureString(item, tBox.Font)
numberOfLines += Math.Floor(StringSize.Width / tBox.Width) + 1
tBox.Height = numberOfLines * tBox.Font.Height + 10

I added a call to that to the TextChanged event handler for each text box. Don't forget that you have to adjust the other items on your form if you make the text box grow. It will overlap other elements if left unchecked.

1 comment:

Terence said...

This is so far the only working approach I came across.

I cant believe that such a simple thing is not available in VB.NET control. Hope I am not overlooking something!!!

However, there seems to be a quirk when there is a very long string in the textbox. The count of line would be off by one when the width of the text reaches like 1500 pixels. Is this due to the inaccuracy of the measurestring function?