whytheq
whytheq

Reputation: 35605

multiline textbox auto adjust it's height according to the amount of text

I have a textbox which can return various strings ranging from 5 characters upto 1000 characters in length. It has the following properties:

Which other properties of the textbox do I need to set to make the following possible?

Upvotes: 7

Views: 28744

Answers (7)

Bharat Prasad Satyal
Bharat Prasad Satyal

Reputation: 11

Add MaxHeight property on TextBox as below.

<TextBox Name="txtSample" MaxHeight="1000" />

Upvotes: 1

maf-soft
maf-soft

Reputation: 2552

I can't believe there is still no really elegant way. This is what I puzzled out:

textBox.Height += textBox.GetPositionFromCharIndex(textBox.Text.Length - 1).Y 
    + 3 + textBox.Font.Height - textBox.ClientSize.Height;

This works by determining the pixel coordinates of the last character of the text.

You can execute this after setting the contents, i.e. in OnLoad of the Form or OnTextChanged of the TextBox control. If the fixed width changes when the user resizes the form, you should also take care of that, i.e. OnResize or OnClientSizeChanged.

TextBox supports the AutoSize property. However, it is already set to true by default, and it is not shown in the property editor or IntelliSense. It is just for font height changes and does not work when using MultiLine = true :( - this is not mentioned in the documentation.

Other options might include using a different control, like RichTextBox or Label. I didn't try yet, but it seems that a Label supports AutoSize much better.

Upvotes: 3

Mike de Klerk
Mike de Klerk

Reputation: 12338

Something like this gives the height of the text as how it is drawn in the textbox itself:

SizeF MessageSize = MyTextBoxControl.CreateGraphics()
                                .MeasureString(MyTextBoxControl.Text,
                                                MyTextBoxControl.Font,
                                                MyTextBoxControl.Width, 
                                                new StringFormat(0));

I am not sure what StringFormat should be but the values StringFormatFlags do not seem to apply to a default TextBox make up.

Now with MessageSize.Height you know the height of the text in the textbox.

Upvotes: 0

vlad
vlad

Reputation: 61

private void tb_TextChanged(object sender, EventArgs e)
{
    tb.Height = (tb.Text.Split('\n').Length + 2 ) * tb.Font.Height;
}

Upvotes: 2

Try this following code:

public partial class Form1 : Form
{
     private const int EM_GETLINECOUNT = 0xba;
     [DllImport("user32", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
     private static extern int SendMessage(int hwnd, int wMsg, int wParam, int lParam);


     public Form1()
     {
        InitializeComponent();
     }

     private void textBox1_TextChanged(object sender, EventArgs e)
     {
        var numberOfLines = SendMessage(textBox1.Handle.ToInt32(), EM_GETLINECOUNT, 0, 0);
        this.textBox1.Height = (textBox1.Font.Height + 2) * numberOfLines;
     }
} 

Upvotes: 11

Harry Cutts
Harry Cutts

Reputation: 1424

There doesn't seem to be any functionality to do this built in to the TextBox class, but the Font class has a Height property that returns the number of pixels between baselines.

It is also possible to find out how many lines the text in the TextBox occupies, as described in this blog post (warning: it's not exactly elegant).

Once you've obtained this information, you should be able to make the TextChanged handler set the height of the TextBox accordingly using some simple maths.

Upvotes: 3

George
George

Reputation: 317

You need to adjust the height of the text box from code. Count the number of lines (this article here can help you with a way to do just that), then set the Textbox.Height to the value you need (number of line * 8px or so, depending on the font used inside the TextBox).

In the linked article solution was to override TextBox control class to be able to get the number of lines; there might be other ways to get the number of lines, but the suggested solution in the article looks quite elegant to me.

Upvotes: 1

Related Questions