Click here to Skip to main content
Click here to Skip to main content

Set TextBox Height

, 7 Sep 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
How to change the height of a single-line textbox

Introduction

This article describes how to set the height of a single-line textbox control. The TextBox control in C# (and VB.NET) ignores the height property and adjusts it to fit the font height. By calculating the exact font size needed, we can set the TextBox to a desired height.

Background

I had a C# project that required a single-line textbox with adjustable height. I found many examples of how to adjust the width, but nothing on how to dynamically change the height of a textbox. I did not want to use multi-line because I wanted to keep the auto-complete features of the single-line textbox.

Using the Code

Single-line textbox height is set by the size of the font, not the TextBox.Height property. This makes it difficult if you are looking for an exact height. Luckily, the font property uses a float for the font size (emSize). You can use fractions of fonts to fine-tune the textbox height.

The calculation the textbox uses to determine its height is:

Height = ( Font Size * Font Line Spacing / Font Em Height ) + 7
  • Font Size - It is easiest to measure font size in pixels, so you do not have to factor in screen dpi.
  • Font Line Spacing - The distance, in design units, between two consecutive lines of text.
  • Font Em Height - Height, in design units of the font's widest letter - typically the letter M.

Textboxes have a 3-pixel lower and 4-pixel upper white space around the font height. Therefore, the calculation increases the height by 7 pixels.

We can reverse this calculation to obtain the font size needed for a desired height:

Font Size = ( height - 7 ) * Font Em Height / Font Line Spacing

This method will return a font object that will set the size of your textbox:

private Font GetFontForTextBoxHeight(int TextBoxHeight, Font OriginalFont)
{
    // What is the target size of the textbox?
    float desiredheight = (float)TextBoxHeight;

    // Set the font from the existing TextBox font.
    // We use the fnt = new Font(...) method so we can ensure that
    //  we're setting the GraphicsUnit to Pixels.  This avoids all
    //  the DPI conversions between point & pixel.
    Font fnt = new Font(OriginalFont.FontFamily,
                        OriginalFont.Size,
                        OriginalFont.Style,
                        GraphicsUnit.Pixel);

    // TextBoxes never size below 8 pixels. This consists of the
    // 4 pixels above & 3 below of whitespace, and 1 pixel line of
    // greeked text.
    if (desiredheight < 8)
        desiredheight = 8;

    // Determine the Em sizes of the font and font line spacing
    // These values are constant for each font at the given font style.
    // and screen DPI.
    float FontEmSize = fnt.FontFamily.GetEmHeight(fnt.Style);
    float FontLineSpacing = fnt.FontFamily.GetLineSpacing(fnt.Style);

    // emSize is the target font size.  TextBoxes have a total of
    // 7 pixels above and below the FontHeight of the font.
    float emSize = (desiredheight - 7) * FontEmSize / FontLineSpacing;
    
    // Create the font, with the proper size.
    fnt = new Font(fnt.FontFamily, emSize, fnt.Style, GraphicsUnit.Pixel);

    return fnt;
}

Whenever you have to set a textbox size, set the font property using the above method:

YourTextBox.Font = GetFontForTextBoxHeight(DesiredHeight, YourTextBox.Font);  

Using the Control

The adjustable Height Textbox is a user control that you can add to your form. It behaves the same as a regular TextBox except:

  • You can set the height in the design view via the Size_AdjustableHeight property.
  • The control, if in single-line mode, will respond to docking and anchoring.

To use the control:

  1. Right-click on your toolbox in Design view.
  2. Click Browse. Navigate to AdjustableHeightTextbox.dll. Hit OK.
  3. Add the control to your form.

Enjoy!

Points of Interest

  • I learned that the .NET TextBox code is basically a wrapper for the old MFC textbox control. That is why it is not very customizable.
  • The GetFontForTextBoxHeight() routine, with some tweaking, could be used for a ComboBox control. The height calculations are close, but still off by a couple of pixels.

There is a lack of information on the inner workings of the textbox control (as with most of the standard .NET controls). I hope this article has saved you hours of searching.

History

  • 2008.09.07 - Posted original article
  • 2008.09.10 - Added a user control version of the textbox and a test project

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

hayes.adrian
Systems Engineer ThomsonReuters Tax & Accounting
United States United States
I am a Senior System Administrator for a 400+ server ASP farm. With such a large farm and limited staff, our goal is to add as much automation as possible to the system. Most of my programming consists of intelligent slack: spending 2 hours to write a program that handles a reoccurring 10 minute manual job.

Comments and Discussions

 
QuestionReply Soon, query on wpf PinmemberDivyaShankar181-Mar-12 2:07 
QuestionTextBox.AutoSize missing? Pinmemberhayes.adrian10-Sep-08 7:00 
AnswerAh! PinmemberIlíon17-Sep-08 6:02 
AnswerRe: TextBox.AutoSize missing? [modified] PinmemberIlíon17-Sep-08 8:23 
I've incorporated this technique in with your other ideas I've used in my TextBox control. You may (or may not) be interested:
private int default_Height = -1;	// Generally: [this.Height = 20;]
[System.ComponentModel.Category("Layout")]
[System.ComponentModel.Description(
    "Set the TextBox.Height to a specific value "
    +"via disabling of the .AutoSize property."
)]
public int Size_ManualHeight
{
    get {return this.Height;}
    set
    {
        if (value != this.Height)
        {
            if (default_Height <= 0)
            {
                default_Height = this.Height;
            }
 
            if( (value > 0)
            && (value != default_Height) )
            {
                if (value > default_Height)
                {
                    this.AutoSize = false;
                    this.Height = value;
                }
                else
                {
                    this.Font = GetFontForTextBoxHeight(
                        value,
                        (this.BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D), 
                        this.Font
                        );
                    this.AutoSize = false;
                    this.Height = value;
                }
            }
            else
            if (!this.AutoSize)
            {
                this.Font = GetFontForTextBoxHeight(
                    default_Height, 
                    (this.BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D), 
                    this.Font
                    );
                this.Height = default_Height;	// Generally: [this.Height = 20;]
                this.AutoSize = true;
            }
        }
    }
}
 
 
[System.ComponentModel.Category("Layout")]
[System.ComponentModel.Description(
    "Set the TextBox.Height to a specific value "
    +"via manipulation of its .Font properties."
)]
public int Size_AdjustedHeight
{
    get {return this.Height;}
    set
    {
        if (value != this.Height)
        {
            if (default_Height <= 0)
            {
                default_Height = this.Height;
            }
 
            this.Font = GetFontForTextBoxHeight(
                value,
                false, 
                this.Font
                );
        }
    }
}
 
 
private static System.Drawing.Font GetFontForTextBoxHeight(
    int TextBoxHeight,
    bool ExtraFontPoints, 
    System.Drawing.Font OriginalFont
)
{
// ...

    // emSize is the target font size.  TextBoxes have a total of
    // 7 pixels above and below the FontHeight of the font.
    //float emSize = (desiredheight - 7) * FontEmSize / FontLineSpacing;
    float desiredoffset = 7f;
    if (ExtraFontPoints)
    {
        desiredoffset = 5f;
    }
    float emSize = (desiredheight - desiredoffset) * FontEmSize / FontLineSpacing;
 
// ...
}
As part of incorporating this technique, I also made a slight mod to the [GetFontForTextBoxHeight()] method, as shown above. My thought is that if I'm using this technique of disabling of the .AutoSize property to explicitly set the textbox .Height *and* the textbox's .BorderStyle != System.Windows.Forms.BorderStyle.Fixed3D then I can squeeze in a couple more pixels of size for the text. My testing of this idea has worked fine.
 

edit: On these extra points for the fontsize:
 
The reason to call the [GetFontForTextBoxHeight()] method in the first place from the [Size_ManualHeight] set accessor when [(value >= default_Height)] is because otherwise the fontsize is too large for the height of the textbox (and the displayed value will probably be clipped). At the same time, if the value set to [Size_ManualHeight] is much less than 15, the text value quickly becomes unreadable. The idea of allowing for 2 extra pixels was a way to somewhat alleviate this. Though, the idea doesn't work out well if the textbox's .BorderStyle == System.Windows.Forms.BorderStyle.Fixed3D
 
The reason to pass the value 'false' in the call to the [GetFontForTextBoxHeight()] method which made from the [Size_AdjustedHeight] set accessor is, of course, because that logic does not override the [this.AutoSize] property.
QuestionIs it official? Pinmembersk8er_boy2878-Sep-08 21:34 
AnswerRe: Is it official? PinmemberIlíon8-Sep-08 23:49 
GeneralRe: Is it official? Pinmembersk8er_boy2878-Sep-08 23:55 
GeneralRe: Is it official? Pinmemberhayes.adrian9-Sep-08 4:19 
GeneralRe: Is it official? Pinmembersk8er_boy2879-Sep-08 22:26 
GeneralRe: Is it official? [modified] Pinmemberhayes.adrian10-Sep-08 5:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141015.1 | Last Updated 7 Sep 2008
Article Copyright 2008 by hayes.adrian
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid