调整文本框的高度

Adapt the height of a TextBox

我正在处理包含多行 TextBox 的 UserControl。

使用我的控件时,可以设置要显示的文本。然后 TextBox 应调整其高度以使文本适合,宽度不能更改。

所以这是处理文本的 属性 :

[Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
public string TextToDisplay
{
    get
    {
        return internalTextBox.Text;
    }
    set
    {
        internalTextBox.Text = value;
        AdaptTextBoxSize();
    }
}

我的第一次尝试很简单:

private void AdaptTextBoxSize()
{
    int nbLignes = internalTextBox.Lines.Length;
    float lineHeight = internalTextBox.Font.GetHeight();
    internalTextBox.Height = (int)((nbLignes) * lineHeight);
}

这没有用,因为它没有考虑两行文本之间的间距。所以文本中的行越多,我被剪掉的就越多。

所以我尝试了这个:

private void AdaptTextBoxSize()
{
    Size textSize = internalTextBox.GetPreferredSize(new Size(internalTextBox.Width, 0));
    internalTextBox.Height = textSize.Height;
}

当文本框中的所有行都短于宽度时,这确实有效。但是当一行比较长,应该裁剪到下一行时,GetPreferredSize() returns宽度比我传的要大,所以高度偏小了。

所以我又改了试这个:

private void AdaptTextBoxSize()
{
    Size textSize = TextRenderer.MeasureText(
                                             internalTextBox.Text, 
                                             internalTextBox.Font, 
                                             new Size(internalTextBox.Width, 0), 
                                             TextFormatFlags.WordEllipsis
                                             );


    internalTextBox.Height = textSize.Height;
}

这次返回的Width是正确的,没有超过我通过的,但是height和上次试的一样。所以它也不起作用。我尝试了 TextFormatFlags 的不同组合,但无法找到获胜的组合...

这是框架的错误吗?

这里真正的问题是,有没有其他我可以尝试的方法,或者其他方法来实现我想要的(即在设置 TextToDisplay 属性 时自动调整高度)?

TextBox.GetPositionFromCharIndex returns 字符的像素位置。这里的position意思是top/left所以我们需要多加一行..

这似乎适用于此:

textBox.Height = textBox.GetPositionFromCharIndex(textBox4.Text.Length - 1).Y + lineHeight;

我得到的行高是这样的:

int lineHeight = -1;
using (TextBox t = new TextBox() { Font = textBox.Font }) lineHeight = t.Height;

我设置了 Height 而不是 ClientSize.Height,这有点不对,除非 BorderStyleNone。你可以改成textBox.ClientSize = new Size(textBox.ClientSize.Width, l + lh);