【问题标题】:Expandable WinForms TextBox可扩展的 WinForms 文本框
【发布时间】:2010-11-15 11:15:56
【问题描述】:

我在 Windows 窗体应用程序中创建了一个文本框,该文本框从一个高度开始,用于在单行中输入文本。但是,如果用户输入包含在控件中的文本,我希望文本框自动增加其高度。

目前,对于这个文本框,我将属性 multiline 和 wordwrap 设置为 true。我尝试使用 TextChanged 事件来确定文本何时被换行,但我找不到任何可以帮助我解决此问题的属性。 Lines 属性不提供任何包装文本的帮助;仅适用于用户按回车键开始新行的文本。

如何让我的文本框在每次文本换行超过文本框宽度时扩展其高度?

【问题讨论】:

    标签: .net winforms textbox height adjustment


    【解决方案1】:

    与其他人发布的想法相同,将其放入您的 textChanged 事件中:

    Dim s As SizeF = TextRenderer.MeasureText(txt.Text, txt.Font, txt.ClientRectangle.Size, TextFormatFlags.WordBreak)
    txt.Height = CInt(s.Height)
    

    您将需要某种最小高度,并且可能需要指定一些填充,但这确实有效。

    【讨论】:

    • 很好的答案,我将在我的项目中使用它。谢谢!
    【解决方案2】:

    如果您愿意改用 RichTextBox(根据我的经验,这是一种带有很多怪癖的脾气暴躁的控件),您可以使用 ContentsResized 事件,它会为您提供新的所需大小:

    private void HandleContentsResized(object sender, ContentsResizedEvenetArgs e)
    {
        int newheight = e.NewRectangle.Height;
    }
    

    【讨论】:

      【解决方案3】:

      我只是为另一个项目的标签控件编写了这个。我从代码项目的某个地方得到了我认为的代码。将其更改为文本框应该与更改基础一样简单。

      public class GrowLabel : Label
      {
          private bool _growing;
          //public bool GrowFontSize { get; set; }
      
          public GrowLabel()
          {
              AutoSize = false;
              //GrowFontSize = false;
          }
      
          public override sealed bool AutoSize
          {
              get { return base.AutoSize; }
              set { base.AutoSize = value; }
          }
      
          private void ResizeLabel()
          {
              if (_growing) return;
              try
              {
                  _growing = true;
      
                  var sz = new Size(Width, Int32.MaxValue);
                  sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.WordBreak);
                  Height = sz.Height;
              }
              finally
              {
                  _growing = false;
              }
          }
      
          protected override void OnTextChanged(EventArgs e)
          {
              base.OnTextChanged(e);
              ResizeLabel();
          }
      
          protected override void OnFontChanged(EventArgs e)
          {
              base.OnFontChanged(e);
              ResizeLabel();
          }
      
          protected override void OnSizeChanged(EventArgs e)
          {
              base.OnSizeChanged(e);
              ResizeLabel();
          }
      }
      

      【讨论】:

      • 谢谢,AdamSane,这也是一个非常好的答案。我发现 Andy's 更简单,于是改用它。
      【解决方案4】:

      AdamSane 的帖子很有帮助,但文本框没有增长。我会做一些修改。我的模组如下:

      class GrowTextBox : TextBox
      {
          private double m_growIndex = 0.0;
          private Timer m_timer;
      
          public GrowTextBox()
          {
              AutoSize = false;
              this.Height = 20;
      
              // Without the timer, I got a lot of AccessViolationException in the System.Windows.Forms.dll.
              m_timer = new Timer();
              m_timer.Interval = 1;
              m_timer.Enabled = false;
              m_timer.Tick += new EventHandler(m_timer_Tick);
      
              this.KeyDown += new KeyEventHandler(GrowTextBox_KeyDown);
          }
      
          void GrowTextBox_KeyDown(object sender, KeyEventArgs e)
          {
              if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A)
              {
                  this.SelectAll();
              }
          }
      
          void m_timer_Tick(object sender, EventArgs e)
          {
              var sz = new Size(Width, Int32.MaxValue);
              sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.TextBoxControl);
      
              m_growIndex = (double)(sz.Width / (double)Width);
      
              if (m_growIndex > 0)
                  Multiline = true;
              else
                  Multiline = false;
      
              int tempHeight = (int)(20 * m_growIndex);
      
              if (tempHeight <= 20)
                  Height = 20;
              else
                  Height = tempHeight;
      
              m_timer.Enabled = false;
          }
      
          public override sealed bool AutoSize
          {
              get { return base.AutoSize; }
              set { base.AutoSize = value; }
          }
      
      
          protected override void OnTextChanged(EventArgs e)
          {
              base.OnTextChanged(e);
              m_timer.Enabled = true;
          }
      
          protected override void OnFontChanged(EventArgs e)
          {
              base.OnFontChanged(e);
              m_timer.Enabled = true;
          }
      
          protected override void OnSizeChanged(EventArgs e)
          {
              base.OnSizeChanged(e);
              m_timer.Enabled = true;
          }
      }
      

      【讨论】:

        【解决方案5】:

        我成功使用下面的代码直到第 10 行,然后它会减少 1 个字符,但这对我有用。不要问我 - 7 和 - 12 之类的随机数,它们与填充有关

            private void txbDescription_TextChanged(object sender, EventArgs e)
            {
                SizeF s = TextRenderer.MeasureText(txbDescription.Text, txbDescription.Font, txbDescription.ClientRectangle.Size, TextFormatFlags.TextBoxControl);
        
                int lines = (int)Math.Ceiling((decimal)Convert.ToInt32(s.Width - 7) / ((decimal)txbDescription.Width - 12));
        
                if (lines == 0)
                {
                    txbDescription.Height = 20;
                }
                else
                {
                    txbDescription.Height = 20 + (lines - 1) * 13;
                }
            }
        

        【讨论】:

          【解决方案6】:

          很遗憾,我无法提供具体细节,但您可能需要进行自定义实现。

          我会派生一个新的文本框类型——ExpandableTextBox——然后你需要手动实现它。

          这似乎也与您要查找的内容相关:http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

          【讨论】:

            猜你喜欢
            • 2021-11-22
            • 2020-05-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多