C# 垂直自动调整文本框控件的大小
在C#形式中,我有一个锚定在四面的面板,里面有一个文本框,锚定在顶部/左侧/右侧 当文本加载到文本框中时,我希望它自动垂直展开,这样我就不需要滚动文本框(如果有更多文本不适合面板,则最多滚动面板)。C# 垂直自动调整文本框控件的大小,c#,textbox,resize,C#,Textbox,Resize,在C#形式中,我有一个锚定在四面的面板,里面有一个文本框,锚定在顶部/左侧/右侧 当文本加载到文本框中时,我希望它自动垂直展开,这样我就不需要滚动文本框(如果有更多文本不适合面板,则最多滚动面板)。 有没有办法用文本框来实现这一点?(我不必使用此控件,因此如果有另一个控件符合描述,请随意提及)您可以使用标签,并将AutoSize设置为true您可以将其锚定到底部,这将确保在调整文本框所属表单的大小时,文本框会垂直调整大小。 此外,更改其大小的文本框可能不是一件优雅的事情,因为它可能会破坏其他组件
有没有办法用文本框来实现这一点?(我不必使用此控件,因此如果有另一个控件符合描述,请随意提及)您可以使用标签,并将AutoSize设置为
true
您可以将其锚定到底部,这将确保在调整文本框所属表单的大小时,文本框会垂直调整大小。
此外,更改其大小的文本框可能不是一件优雅的事情,因为它可能会破坏其他组件的显示方式。为什么不给它一个最大尺寸,而不是调整大小呢?我建议使用
首先创建一个Graphics
对象,然后调用MeasureString
,传递字符串和文本框的字体
示例
string text = "TestingTesting\nTestingTesting\nTestingTesting\nTestingTesting\n";
// Create the graphics object.
using (Graphics g = textBox.CreateGraphics()) {
// Set the control's size to the string's size.
textBox.Size = g.MeasureString(text, textBox.Font).ToSize();
textBox.Text = text;
}
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;
}
<asp:TextBox ID="txtValue" TextMode="MultiLine" Text='<%# Eval("Value") %>' runat="server" MaxLength="500" Width="700px" Rows='<%# GetRows(Eval ("Value")) %>' ></asp:TextBox>
您还可以通过仅设置textBox.Size.Height
属性并使用MeasureString
重载将其限制为垂直轴,该重载也接受int width
编辑
正如SLaks指出的,另一个选择是使用。这样就不需要创建图形
对象
textBox.Size = TextRenderer.MeasureString(text, textBox.Font).ToSize();
在这里,您可以使用Hans的技术限制垂直调整大小,通过
int.MaxValue
height将一个额外的Size
参数传递给MeasureString
。我假设这是一个多行文本框,您允许它垂直增长。该代码运行良好:
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属性。当前选择的答案不处理没有空格的行,例如“jjjjjjjjjx1000”(想想如果有人粘贴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;
}
尝试以下方法:
aspx.cs代码
string text = "TestingTesting\nTestingTesting\nTestingTesting\nTestingTesting\n";
// Create the graphics object.
using (Graphics g = textBox.CreateGraphics()) {
// Set the control's size to the string's size.
textBox.Size = g.MeasureString(text, textBox.Font).ToSize();
textBox.Text = text;
}
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;
}
<asp:TextBox ID="txtValue" TextMode="MultiLine" Text='<%# Eval("Value") %>' runat="server" MaxLength="500" Width="700px" Rows='<%# GetRows(Eval ("Value")) %>' ></asp:TextBox>
aspx代码
string text = "TestingTesting\nTestingTesting\nTestingTesting\nTestingTesting\n";
// Create the graphics object.
using (Graphics g = textBox.CreateGraphics()) {
// Set the control's size to the string's size.
textBox.Size = g.MeasureString(text, textBox.Font).ToSize();
textBox.Text = text;
}
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;
}
<asp:TextBox ID="txtValue" TextMode="MultiLine" Text='<%# Eval("Value") %>' runat="server" MaxLength="500" Width="700px" Rows='<%# GetRows(Eval ("Value")) %>' ></asp:TextBox>
您忘记处理g
。您应该调用TextRenderer.MeasureString
。它可以工作,但不处理没有空格的行。大卫写的那个that@Hans如果它是一个单行文本框呢?那么你不在乎它的高度,当然,它是固定的。最好的答案。次要调整:GetLineFromCharIndex()不计算尾随的crlf,因此请检查该值,并在需要时添加+1。@amonroejj这很奇怪。我只是试了一下,对我来说没必要。我使用的是.NETFramework 4.7.2。这是用于.NETCore的吗?