Подтвердить что ты не робот

С# Изменить размер текстового поля для соответствия содержимому

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

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

Ответ 3

Ваша привязка к неправильному событию, и вы не можете использовать графический объект в объекте 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);
}

}

Ответ 4

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

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

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

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

Ответ 5

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

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

Ответ 6

Попробуйте следующее:

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 - ваш предыдущий код просочился бы ужасно!

Ответ 7

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

Ответ 8

Graphics.Measure string вы можете сделать 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);

Проблема заключается в том, что вы просто не можете создать объект Графика, просто выделив его, поскольку у него нет открытого конструктора, поэтому вам лучше пойти и использовать TextRenderer.MeasureText, как это сделано в http://msdn.microsoft.com/en-us/library/y4xdbe66.aspx

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

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

Ответ 9

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 10

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

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

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