C# 调整文本框大小以适应内容

33

我正在编写一个程序,用户应该能够在 TextBox 中编写文本。我希望 TextBox 能够自动调整大小,以适应文本内容。

我尝试了以下方法:

private void textBoxTitle_TextChanged(object sender, TextChangedEventArgs e)
{
    System.Drawing.Font myFont = new System.Drawing.Font("Verdana", 8);
    System.Drawing.SizeF mySize = e.Graphics.MeasureString("This is a test", myFont);
    this.textBoxTitle.Width = (int)Math.Round(mySize.Width, 0);
}

我遇到一个错误,说Graphics不能用于TextChangedEventArgs。有没有其他方法可以调整TextBox的大小?


你是在尝试使用Silverlight吗? - Mustafa Ekici
10个回答

71

您应该尝试像下面这样编写代码。这对我很有效。

private void textBox1_TextChanged(object sender, EventArgs e)
{
  Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
  textBox1.Width = size.Width;
  textBox1.Height = size.Height;
}

如需更多信息,请参考TextRenderer.MeasureText()


我有一个包含TextBox的用户控件。当文本增长时,只有宽度会增加,即使宽度超过其父级。如何确定父级的宽度,然后换行文本并增加高度? - Meyssam Toluie

9

我有同样的问题,但我用了更简单的方法解决了它。

我使用了标签控件的AutoSize属性。我在表单中添加了一个不可见的标签,并将其AutoSize属性设置为True。当我需要更改文本框的大小时,我使用以下代码:

MyLabel.Text = MyTextBox.Text;
MyTextBox.Size = MyLabel.Size;

我设置标签的最大和最小尺寸以获得更好的结果。 玩得愉快


太好了!我设置了 TextBox 嵌入在 Panel 中,并将 Label 的 MaximumSize 设置为容器的大小可以随着 TextBox 的大小调整而变化。此外,我设置了 MyLabel.Text = MyTextBox.Text + " "; 这样当您按下“Enter”键时,标签的大小会改变(如果 CRLF 后没有字符,则不会更改标签的大小)。谢谢! - John Kurtz

9

我添加了这个答案,因为我在其他答案中没有看到文本框的 固定宽度 方面被讨论。如果你的文本框有一个固定的宽度,而你只想调整它的高度,可以尝试以下方法:

像这样的代码可以给出多行自动换行文本框中文本的实际高度:

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

我不确定StringFormat应该是什么,但StringFormatFlags的值似乎不适用于默认的TextBox组件。

现在有了MessageSize.Height,您就知道文本框中文本的高度。


4

您绑定了错误的事件,并且不能在TextChangedEventArgs对象中使用图形对象。

尝试使用TextChanged事件。以下代码片段可行:

public Form1()
{
    InitializeComponent();

    this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
}

void textBox1_TextChanged(object sender, EventArgs e)
{
    System.Drawing.SizeF mySize = new System.Drawing.SizeF();

    // Use the textbox font
    System.Drawing.Font myFont = textBox1.Font;

    using (Graphics g = this.CreateGraphics())
    {
        // Get the size given the string and the font
        mySize = g.MeasureString(textBox1.Text, myFont);
    }

    // Resize the textbox 
    this.textBox1.Width = (int)Math.Round(mySize.Width, 0);
}

}


3

首先,创建一个方法使文本框适应其内容。

Original Answer翻译成"最初的回答"。

private void AutoSizeTextBox(TextBox txt)
{
    const int x_margin = 0;
    const int y_margin = 2;
    Size size = TextRenderer.MeasureText(txt.Text, txt.Font);
    txt.ClientSize =
        new Size(size.Width + x_margin, size.Height + y_margin);
}

当文本更改时,使用TextChanged事件处理程序调用AutoSizeTextBox()函数,使TextBox适合其文本。


private void txtContents_TextChanged(object sender, EventArgs e)
{
    AutoSizeTextBox(sender as TextBox);
}

这就是全部内容,想要了解更多信息请查看:

调整文本框大小以适应其文本


虽然这个链接可能回答了问题,但最好在这里包含答案的必要部分,并提供参考链接。仅有链接的答案如果链接页面发生更改,则可能变得无效。仅仅是一个链接的答案可能会被删除 - adiga

1

试试这个:

using System.Drawing;
...

private void textBoxTitle_TextChanged(object sender, TextChangedEventArgs e)
{
    // Determine the correct size for the text box based on its text length   

    // get the current text box safely
    TextBox tb = sender as TextBox;
    if (tb == null) return;

    SizeF stringSize;

    // create a graphics object for this form
    using(Graphics gfx = this.CreateGraphics())
    {
        // Get the size given the string and the font
        stringSize = gfx.MeasureString(tb.Text, tb.Font);
    }

    // Resize the textbox 
    tb.Width = (int)Math.Round(stringSize.Width, 0);

}

基本上,您可以为表单创建自己的Graphics对象,然后根据TextBox的文本和字体进行度量。 using将正确处理Graphics对象的释放 - 您以前的代码会泄漏得非常严重!

1
无论目标是什么。
如果文本框的大小应该根据字符串动态设置,这个字符串应该是盒子里面的文本,那么没有好的选择原因:MeasureString使用通常的字符串格式化程序作为其宽度和高度的分隔符。也就是说,回车和换行符也被解析。导致sizeF.Width和sizeF.Height。
根据字符串(及其字体和行数),这两个变量可能会携带有时无法用作文本框宽度/高度值的值(因为它们可能比父窗体的值更大,这将调整文本框的大小,使其左侧和底部边界超出父窗体的边界)。
一些解决方案仍然可用,具体取决于想要实现的目标。
一个想法是: 在设计器中创建一个文本框,大小为100 X 100。启用自动换行
在文本框的 OnTextChanged 事件处理程序中,我们只需将文本框的宽度调整为由我们自己定义的值(例如parentform.Width或另一个硬编码值)。
这会导致单词换行重新计算文本框中的字符串,并重新排列文本框内所有字符,因为启用了自动换行。
文本框的高度可以硬编码设置为parentform.Height,例如。
但更好的方法是根据方法texbox.GetPositionFromCharIndex(textbox.TextLength -1)返回的ReturnValue(Point)的Y值动态设置高度。然后,使用Math.Min()确定哪个较小(即parentform.Height或Point.Y),并将文本框大小重置为新的Size(previousDeterminedWidth, nowDeterminedHeight)。
请记住(如果启用滚动条),在宽度计算中添加约17像素。
此致最好的问候。

1
你需要使用表单的CreateGraphics()方法创建一个Graphics实例来测量字符串。
TextChangedEventArgs类没有Graphics属性,这是传递给Paint事件处理程序的PaintEventArgs类的属性。

0

在编程中,你可以使用 PaintEventArgs 而不是 TextChangedEventArgs 来进行字符串的测量。

我认为你想要的是这个:

System.Drawing.Font myFont = new System.Drawing.Font("Verdana", 8);
Graphics graphics = this.CreateGraphics();
SizeF textSize = graphics.MeasureString("This is a test", myFont);

问题在于你不能简单地分配一个Graphics对象,因为它没有公共构造函数,所以最好使用TextRenderer.MeasureText,就像http://msdn.microsoft.com/en-us/library/y4xdbe66.aspx中所做的那样。
TextRenderer不太准确,因为它使用GDI,而Graphics使用GDI+,所以也许你应该在从Width属性得到的值上留出一点余地。
希望这可以帮助到你。

Graphics g = Graphics.FromHwnd(txtBox.Handle); 的意思是什么? - Pedro77

0
你尝试过设置 yourTextBox.AutoSize = true; 吗? 这个属性可能在 GUI 设计器中被隐藏了,但你可以在表单构造函数中,在 InitializeComponent(); 调用之后立即设置它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接