none
How to resize a TextBox to fit the text in it?

    Question

  • OK, I'm hitting a very unexpected stumbling point here.  I've got a series of Textboxes displayed in a TableLayoutPanel.  Each of these textboxes shares a row with a button.  The button is of fixed width and the TextBox fills the remainder of the row.  The behavior I want from the TextBox is to automatically resize itself in the Y-axis if the text in it is multi-line. 

    Right now, I'm automatically resizing the TextBox on the TextChanged event.  This works partially.  I can get the number of lines of text with a GetLineFromCharIndex call that takes the Index of the last character of text in the TextBox.  I then multiply the number of lines by the height of the font, and add the difference between the Bounds.Height and ClientSize.Height to figure out the size the TextBox should be.

    Unfortunately, all the methods I have tried to calculate the Font height don't work.  Font.Height returns a value that is accurate for the first line of text but then is too large for subsequent lines of text.  The result is that the TextBox quickly starts getting too large as multiple lines of text are added.  With Times New Roman 13 point, the excess is about 1 pixel per text line after the 1st line.  I can fudge factor this out but only for this particular font and size.  With (for example) Forte 20 point, the overesize is something like 5 pixels per line which causes the TextBox to balloon out of control very quickly.

    I've tried looking at the pixel size conversion of FontFamily GetLineSpacing, GetCellAscent and Get CellDescent.  GetLine Spacing and Ascent + Descent both give lines spacings that are consistently too small.

    Is there any way to actually get the vertical size of a font in a TextBox?  This seems like something that should be very simple but I can't seem to get it to work.  Suggestions?

     

    Wednesday, May 10, 2006 3:58 PM

Answers

  • Whoop, nevemind, I figured it out.  TextRenderer.MeasureText does the trick.   Here's code if anyone is interested:

    void DetailRowTextBox_TextChanged(object sender, EventArgs e)

    {

    Font tempFont = ((CitationManagerMain)(this.TopLevelControl)).DetailFont as Font;

    int textLength = ((TextBox)(sender)).Text.Length;

    int textLines = ((TextBox)(sender)).GetLineFromCharIndex(textLength) + 1;

    int Margin = ((TextBox)(sender)).Bounds.Height - ((TextBox)(sender)).ClientSize.Height;

    ((TextBox)(sender)).Height = (TextRenderer.MeasureText(" ", tempFont).Height * textLines)

    + Margin + 2;

    }

    Text.Length gets the number of characters in the TextBox.  GetLineFromCharIndex gets the number of lines of text in the Textbox (this catches lines created by both carriage returns as well as wrapped lines).  Margin is simply the space between the usable area of the textbox and its outer edges.  I call MeasureText on a space to calculate the height of the font, multiply it by the number of lines, add the Margin and a 2 pixel fudge factor and it works beautifully.

    Wednesday, May 10, 2006 4:32 PM

All replies

  • Whoop, nevemind, I figured it out.  TextRenderer.MeasureText does the trick.   Here's code if anyone is interested:

    void DetailRowTextBox_TextChanged(object sender, EventArgs e)

    {

    Font tempFont = ((CitationManagerMain)(this.TopLevelControl)).DetailFont as Font;

    int textLength = ((TextBox)(sender)).Text.Length;

    int textLines = ((TextBox)(sender)).GetLineFromCharIndex(textLength) + 1;

    int Margin = ((TextBox)(sender)).Bounds.Height - ((TextBox)(sender)).ClientSize.Height;

    ((TextBox)(sender)).Height = (TextRenderer.MeasureText(" ", tempFont).Height * textLines)

    + Margin + 2;

    }

    Text.Length gets the number of characters in the TextBox.  GetLineFromCharIndex gets the number of lines of text in the Textbox (this catches lines created by both carriage returns as well as wrapped lines).  Margin is simply the space between the usable area of the textbox and its outer edges.  I call MeasureText on a space to calculate the height of the font, multiply it by the number of lines, add the Margin and a 2 pixel fudge factor and it works beautifully.

    Wednesday, May 10, 2006 4:32 PM
  • Hi Den,

    Your solution is really a great one! But I don't understand C properly. Will you please give me a vb version of this code?

    Regards!

    Kapalic

    Wednesday, February 28, 2007 3:05 PM
  • Have you tried the PreferredHeight property of the textbox?

    http://msdn2.microsoft.com/en-us/library/system.windows.forms.textboxbase.preferredheight.aspx

     

    Monday, March 12, 2007 3:46 PM