调整文本框的高度

时间:2018-07-04 10:37:32

标签: c# winforms autosize

我正在使用一个包含多行TextBox的UserControl。

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

这是处理文本的属性:

[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()返回的宽度大于我通过的宽度,因此高度太小。

所以我再次更改并尝试了这个:

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


    internalTextBox.Height = textSize.Height;
}

这次返回的Width是正确的,因为它不超过我通过的宽度,但是高度与先前的尝试相同。因此它也不起作用。我为TextFormatFlags尝试了不同的组合,但找不到成功的组合...

这是框架中的错误吗?

这里的真正问题是,我是否可以尝试另一件事,或者实现我想要的目标(即在设置TextToDisplay属性时自动调整高度)?

1 个答案:

答案 0 :(得分:2)

TextBox.GetPositionFromCharIndex返回字符的像素位置。这里的位置表示顶部/左侧,因此我们需要再添加一行。

这似乎在这里起作用:

notify_one()

我得到这样的行高:

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

bool is_ready_1(false);
bool is_ready_2(false);
std::mutex m;
std::condition_variable cv;

void test1()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::unique_lock<std::mutex> lk(m);
    is_ready_1 = true;
    cv.notify_one();
}
void test2()
{
    std::this_thread::sleep_for(std::chrono::seconds(6));
    std::unique_lock<std::mutex> lk(m);
    is_ready_2 = true;
    cv.notify_one();
}

int main()
{
    std::thread t1(test1);
    std::thread t2(test2);

    std::unique_lock<std::mutex> lk(m);
    while (!is_ready_1)
    {
        cv.wait(lk);
        if (is_ready_1)
            std::cout << "Spurious wake-1 up!\n";
    }

    while (!is_ready_2)
    {
         cv.wait(lk);
         if (is_ready_2)
         std::cout << "Spurious wake-2 up!\n";
    }
    t1.join(); 
    t2.join();
    system("pause");
}

我设置了textBox.Height = textBox.GetPositionFromCharIndex(textBox4.Text.Length - 1).Y + lineHeight; 而不是int lineHeight = -1; using (TextBox t = new TextBox() { Font = textBox.Font }) lineHeight = t.Height; ,除非HeightClientSize.Height,否则这是错误的。您可以更改为BorderStyle