可扩展的 WinForms 文本框

发布于 2024-07-30 03:44:39 字数 290 浏览 16 评论 0 原文

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

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

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

I have created a textbox in a Windows Forms application that starts out at a height for entering text in a single line. But I would like the textbox to automatically increase its height if the user enters text that is wrapped within the control.

Currently, for this textbox, I have the properties multiline and wordwrap set to true. I've tried using the TextChanged event to determine when the text has been wrapped but I'm unable to find any property that will help me with this. The Lines property does not provide any help with wrapped text; only for text that the user has hit enter to begin a new line.

How can I get my textbox to expand its height each time the text wraps past the width of the textbox?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

趁年轻赶紧闹 2024-08-06 03:44:39

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

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

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

Same kind of idea as others have posted, put this in your textChanged event:

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

You will need some kind of minimum height, and possibly to specify some padding, but this does work.

坚持沉默 2024-08-06 03:44:39

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

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

I just wrote this for a label control for a different project. I got the code off of code project somewhere I think. Changing it to a Textbox should be as simple as changing the base.

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();
    }
}
与之呼应 2024-08-06 03:44:39

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

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

If you're willing to use a RichTextBox instead (which, in my experience, is kind of a grumpy control that comes with lots of quirks), you can use the ContentsResized event, which gives you the new required size:

private void HandleContentsResized(object sender, ContentsResizedEvenetArgs e)
{
    int newheight = e.NewRectangle.Height;
}
沒落の蓅哖 2024-08-06 03:44:39

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

AdamSane's post was helpful but the textbox didn't grow. I'd to make some modifications. My mods are below:

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;
    }
}
仄言 2024-08-06 03:44:39

我成功地使用了下面的代码,直到大约第 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;
        }
    }

I'm using the code below with success until about the 10th line, then it gets 1 character off, but this works for me. Don't ask me about the random numbers like - 7 and - 12, they have something to do with padding

    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;
        }
    }
橘和柠 2024-08-06 03:44:39

不幸的是,我无法提供具体细节,但您可能需要进行自定义实现。

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

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

Unfortunately, I can't provide specifics but you are going to need to probably do a custom implementation.

I'd derive a new text box type -- ExpandableTextBox -- and then you'll need to implement it by hand.

This also seems relevant to what you are looking for: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/11dfb280-b113-4ddf-ad59-788f78d2995a

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文