【问题标题】:C# Resize textbox to fit contentC# 调整文本框大小以适应内容
【发布时间】:2011-12-24 07:25:28
【问题描述】:

我正在编写一个程序,用户应该能够在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 中尝试这个吗?

标签: c# winforms textbox resize


【解决方案1】:

首先,创建使 TextBox 适合其内容的方法。

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);
}

就是这样,更多信息:

resize-a-textbox-to-fit-its-text

【讨论】:

【解决方案2】:

我遇到了同样的问题,我用更简单的方法解决了。

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

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

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

【讨论】:

  • 嘭!让它与停靠在面板中的 TextBox 一起工作,并且具有 MaximumSize 的 Label 设置了 TextBox 容器的大小调整。另外,我设置 MyLabel.Text = MyTextBox.Text + " ";这样,当您按“Enter”键时,标签的大小会发生变化(它不会在 CRLF 之后没有字符的情况下更改标签大小)。谢谢!
【解决方案3】:

无论目标是什么。

如果文本框的大小应该根据字符串动态设置,应该是这个框内的文本,没有很好的选择

原因: 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 个像素。

最好的问候

【讨论】:

    【解决方案4】:

    您应该尝试如下代码。它对我很有效。

    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。当 Text 增长很多时,只有宽度会增加,即使宽度会超过其父级。如何确定父级的宽度然后将文本换行并增加高度?
    【解决方案5】:

    我添加了这个答案,因为我没有看到文本框的 fixed width 方面正在讨论中。如果您的文本框有固定宽度,并且只想调整其高度,则可以执行以下操作:

    这样的东西给出了文本的高度,就像它在多行自动换行文本框本身中的绘制方式一样:

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

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

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

    【讨论】:

      【解决方案6】:

      Graphics.Measure 字符串你可以在 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中所做的那样/p>

      TextRenderer 不太准确,因为它使用 GDI,而 Graphics 使用 GDI+,所以也许你应该在从 Width 属性获得的值上留一点余量。

      希望对你有帮助

      【讨论】:

      • 怎么样:图形 g = Graphics.FromHwnd(txtBox.Handle); ?
      【解决方案7】:

      您是否尝试设置yourTextBox.AutoSize = true;? 该属性可能隐藏在 GUI 设计器中,但您可以在 InitializeComponent(); 调用后立即在表单构造函数中设置它。

      【讨论】:

        【解决方案8】:

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

        尝试使用 TextChanged 事件。以下 sn-p 正在工作:

        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);
        }
        

        }

        【讨论】:

          【解决方案9】:

          试试这个:

          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 对象,然后根据文本框的文本和字体对其进行测量。 using 将正确处理 Graphics 对象 - 您之前的代码会严重泄露!

          【讨论】:

            【解决方案10】:

            您将需要使用表单的 CreateGraphics() 方法来创建 Graphics 实例来测量字符串。

            TextChangedEventArgs 类没有Graphics 属性,即传递给Paint 事件处理程序的PaintEventArgs 类的属性

            【讨论】:

              猜你喜欢
              • 2020-04-14
              • 2011-08-20
              • 1970-01-01
              • 1970-01-01
              • 2020-10-09
              • 2011-02-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多