Автоматическое управление текстовым полем по вертикали
В форме С# у меня есть панель, привязанная всеми сторонами, а внутри - текстовое поле, закрепленное сверху/влево/вправо.
Когда текст загружается в текстовое поле, я хочу, чтобы он автоматически расширялся по вертикали, так что мне не нужно прокручивать текстовое поле (прокрутите панель максимум, если текст больше не подходит для панели),
есть ли способ сделать это с помощью текстового поля? (я не должен использовать этот элемент управления, поэтому, если есть другой элемент управления, который соответствует описанию, не стесняйтесь упоминать его)
Ответы
Ответ 1
Я предполагаю, что это многострочное текстовое поле, и вы позволяете ему расти вертикально. Этот код работал хорошо:
private void textBox1_TextChanged(object sender, EventArgs e) {
Size sz = new Size(textBox1.ClientSize.Width, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.WordBreak;
int padding = 3;
int borders = textBox1.Height - textBox1.ClientSize.Height;
sz = TextRenderer.MeasureText(textBox1.Text, textBox1.Font, sz, flags);
int h = sz.Height + borders + padding;
if (textBox1.Top + h > this.ClientSize.Height - 10) {
h = this.ClientSize.Height - 10 - textBox1.Top;
}
textBox1.Height = h;
}
Вы должны сделать что-то разумное, когда текстовое поле пуст, например установка свойства MinimumSize.
Ответ 2
Текущий выбранный ответ НЕ обрабатывает строки без пробелов, таких как "jjjjjjjjjjjjjjjjjjj" x1000 (подумайте, что произойдет, если кто-то вставил URL-адрес)
Этот код решает эту проблему:
private void txtBody_TextChanged(object sender, EventArgs e)
{
// amount of padding to add
const int padding = 3;
// get number of lines (first line is 0, so add 1)
int numLines = this.txtBody.GetLineFromCharIndex(this.txtBody.TextLength) + 1;
// get border thickness
int border = this.txtBody.Height - this.txtBody.ClientSize.Height;
// set height (height of one line * number of lines + spacing)
this.txtBody.Height = this.txtBody.Font.Height * numLines + padding + border;
}
Ответ 3
Вы можете использовать Label и установить AutoSize на true
.
Ответ 4
Я бы предложил использовать Graphics.MeasureString
.
Сначала вы создаете объект Graphics
, затем вызываете MeasureString
на нем, передавая строку и шрифт текстового поля.
Пример
string text = "TestingTesting\nTestingTesting\nTestingTesting\nTestingTesting\n";
// Create the graphics object.
using (Graphics g = textBox.CreateGraphics()) {
// Set the control size to the string size.
textBox.Size = g.MeasureString(text, textBox.Font).ToSize();
textBox.Text = text;
}
Вы также можете ограничить его вертикальной осью, установив только свойство textBox.Size.Height
и используя перегрузку MeasureString
, которая также принимает int width
.
Edit
Как отметил Слэкс, другой вариант использует TextRenderer.MeasureString
. Таким образом, нет необходимости создавать объект Graphics
.
textBox.Size = TextRenderer.MeasureString(text, textBox.Font).ToSize();
Здесь вы можете ограничить вертикальное изменение размера с помощью техники Ганса, передав дополнительный параметр Size
на MeasureString
с высотой int.MaxValue
.
Ответ 5
Вы можете привязать его к нижней части, чтобы обеспечить изменение размера текстового поля по вертикали, когда изменяется форма, к которой она принадлежит.
Кроме того, текстовое поле, которое меняет свой размер, может быть не изящным, поскольку оно может нарушить способ отображения других компонентов. Почему бы вам не указать максимальный размер, а не изменить его размер?
Ответ 6
Попробуйте этот подход:
код aspx.cs
protected int GetRows(object value) {
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
return 1;
var contentTrimmed = value.ToString().Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ').Trim();
var length = (decimal)contentTrimmed.Length;
if (length == 0)
return 1;
int res = 0;
decimal maxLength = 56;
using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1)))
{
SizeF sizeRef = graphics.MeasureString("W", new Font("Segoe UI", 13, FontStyle.Regular, GraphicsUnit.Pixel));
maxLength = maxLength * (decimal)sizeRef.Width;
SizeF size = graphics.MeasureString(contentTrimmed, new Font("Segoe UI", 13, FontStyle.Regular, GraphicsUnit.Pixel));
length = (decimal)size.Width;
}
res = (int)Math.Round(length / (decimal)maxLength, MidpointRounding.AwayFromZero);
if (res == 0)
return 1;
return res;
}
код aspx
<asp:TextBox ID="txtValue" TextMode="MultiLine" Text='<%# Eval("Value") %>' runat="server" MaxLength="500" Width="700px" Rows='<%# GetRows(Eval ("Value")) %>' ></asp:TextBox>