Automatically adjust multi-line text field according to the amount of text

I have a text box that can return various strings from 5 characters to 1000 characters long. It has the following properties:

  • multiline = true
  • wordwrap = true

What other properties of the text box do I need to set in order to make the following possible:

  • The field width should be fixed.
  • The window height for automatic adjustment depending on how much text it returns, for example, if the text works on 3 lines, then it is adjusted to 3 lines in height.
+7
source share
7 answers

Try the 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; } } 
+8
source

It seems that there is no function for this built-in to the TextBox class, but the Font class has a Height property that returns the number of pixels between the baselines.

You can also find out how many lines the text in the TextBox takes up as described in this blog post (warning: this is not exactly elegant).

Once you get this information, you can get the TextChanged handler to set the height of the TextBox accordingly using simple mathematical calculations.

+3
source

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

The solution to the related article was to override the TextBox control class to be able to get the number of rows; There may be other ways to get the number of rows, but the proposed solution in the article looks pretty elegant for me.

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

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

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

I'm not sure what StringFormat should be, but the StringFormatFlags values ​​do not seem to apply to the default TextBox layout.

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

0
source

I can’t believe that there is still no elegant way. Here is what I puzzled:

 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 do this after setting the content, i.e. in the OnLoad of the Form element or OnTextChanged of the TextBox control. If the fixed width changes when the user resizes the form, you should also take care of this, i.e. OnResize or OnClientSizeChanged .

TextBox supports the AutoSize property. However, it is already set to true by default, and it does not appear in the Property Editor or IntelliSense. This is easy to change the font height and does not work when using MultiLine = true :( - this is not mentioned in the documentation .

Other options may include the use of another control, such as RichTextBox or Label . I haven't tried it yet, but Shortcut seems to support AutoSize much better.

0
source

Add the MaxHeight property to the TextBox as shown below.

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

0
source

All Articles