C # Изменение размера текстового поля, чтобы соответствовать содержанию - PullRequest
23 голосов
/ 08 ноября 2011

Я пишу программу, в которой пользователь должен иметь возможность писать текст в текстовом поле.Я бы хотел, чтобы текстовое поле само меняло размер, чтобы оно соответствовало содержанию.Я пробовал следующее:

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.Есть ли другой способ изменить размер текстового поля?

Ответы [ 10 ]

54 голосов
/ 08 ноября 2011

Вы должны попробовать код что-то вроде ниже.Это хорошо сработало для меня.

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

6 голосов
/ 29 ноября 2013

Я добавляю этот ответ, так как не вижу аспект fixed width текстового поля, обсуждаемого ни в одном другом. Если у вас есть фиксированная ширина для вашего текстового поля, и вы хотите настроить только его высоту, вы можете сделать что-то вроде следующего:

Что-то вроде этого дает высоту текста в том виде, в каком он нарисован в самом многострочном текстовом поле со словосочетанием:

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

Я не уверен, что StringFormat должно быть, но значения StringFormatFlags, кажется, не применяются к макияжу по умолчанию TextBox.

Теперь с MessageSize.Height вы знаете высоту текста в текстовом поле.

4 голосов
/ 08 ноября 2011

Ваша привязка к неправильному событию, и вы не можете использовать графический объект в объекте TextChangedEventArgs.

Попробуйте использовать событие TextChanged.Работает следующий фрагмент:

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

}

3 голосов
/ 01 мая 2017

У меня была та же проблема, и я решил ее более простым способом.

Я использовал свойство AutoSize элемента управления Label. Я добавил невидимую метку в форму, установил для свойства AutoSize значение True.Когда мне нужно изменить размер моего TextBox, я использую этот код:

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

Я устанавливаю максимальный и минимальный размер метки для лучших результатов.Веселись

1 голос
/ 08 ноября 2011

Попробуйте это:

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 объект для формы, а затем измеряете его на основе текста и шрифта TextBox. using правильно удалит объект Graphics - ваш предыдущий код мог бы ужасно просочиться!

1 голос
/ 08 ноября 2011

Вам потребуется использовать метод CreateGraphics () формы, чтобы создать экземпляр Graphics для измерения строки.

Класс TextChangedEventArgs не имеет свойства Graphics, то есть свойства класса PaintEventArgs, передаваемого обработчику событий Paint

0 голосов
/ 05 июля 2019

сначала создайте метод, чтобы 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);
}

Вот и все, для большей информации:

размер-а-текстовое поле-в-отделке его текстом

0 голосов
/ 31 января 2013

Какой бы ни была цель.

Если размер текстового поля должен динамически устанавливаться на основе строки, которая должна быть текстом внутри этого поля, , то нет удобной опции .

Причины: MeasureString использует обычные формататоры строк в качестве разделителей для своей собственной ширины и высоты. Значения, возврат каретки и перевод строки тоже анализируются. В результате чего размер F.Width и sizeF.Height.

В зависимости от строки (и ее шрифта, и количества строк) обе эти переменные могут нести значения, которые иногда бесполезны для использования в качестве значений ширины / высоты текстового поля (поскольку они могут быть больше, чем родительская форма значения, и это приведет к изменению размера текстового поля до размера с левой и нижней границами за пределами границ родительской формы ).

Некоторые решения по-прежнему доступны, в зависимости от цели, которую хотелось бы достичь.

Одна идея была бы: Создайте текстовое поле в конструкторе, размер = 100 X 100. включить перенос слов .

В обработчике события OnTextChanged текстового поля мы просто изменяем ширину текстового поля до значения, определенного самим собой (например, parentform.Width или другого жесткого значения).

Это заставит перенос слов пересчитать строку в текстовом поле и переставит все символы внутри текстового поля, потому что перенос слов включен.

Для высоты текстового поля может быть установлено значение parentform.Height, например.

НО, лучше: установить высоту динамически, основываясь на значении Y ReturnValue (Point) метода texbox.GetPositionFromCharIndex (textbox.TextLength -1). Затем с помощью Math.Min () определите, что меньше (parentform.Height или Point.Y), и установите для размера текстового поля новый размер (previousDeterminedWidth, nowDeterminedHeight).

Пожалуйста, имейте в виду (если полосы прокрутки включены), чтобы добавить около 17 пикселей в расчет ширины.

С наилучшими пожеланиями

0 голосов
/ 08 ноября 2011

Графика. Строка измерения, которую вы можете сделать o 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

TextRenderer менее точен, потому что он использует GDI, а Graphics использует GDI +, поэтому, возможно, вам следует оставить небольшой запас для значения, которое вы получаете из свойства Width.

Надеюсь, это поможет

0 голосов
/ 08 ноября 2011

Вы пытались установить yourTextBox.AutoSize = true;?Это свойство может быть скрыто в конструкторе графического интерфейса, но вы можете установить его в конструкторе формы сразу после вызова InitializeComponent();.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...