확장 가능한 winforms 텍스트 상자
-
05-07-2019 - |
문제
한 줄로 텍스트를 입력하기 위해 높이에서 시작하는 Windows 양식 응용 프로그램에서 텍스트 상자를 만들었습니다. 그러나 사용자가 컨트롤 내에 포장 된 텍스트를 입력하면 텍스트 상자가 자동으로 높이를 높이고 싶습니다.
현재이 텍스트 박스의 경우 속성 멀티 린 및 워드 트랩이 true로 설정되어 있습니다. TextChanged 이벤트를 사용하여 텍스트가 래핑 된시기를 결정했지만 이에 도움이되는 속성을 찾을 수 없습니다. 라인 속성은 랩핑 된 텍스트에 대한 도움을 제공하지 않습니다. 사용자가 새 줄을 시작하기 위해 Enter를 누른 텍스트에 대해서만.
텍스트 상자가 텍스트 상자의 너비를 지나갈 때마다 텍스트 상자가 높이를 확장하도록하려면 어떻게해야합니까?
해결책
다른 사람들이 게시 한 것과 동일한 아이디어, 이것을 텍스트 변경 이벤트에 넣습니다.
Dim s As SizeF = TextRenderer.MeasureText(txt.Text, txt.Font, txt.ClientRectangle.Size, TextFormatFlags.WordBreak)
txt.Height = CInt(s.Height)
당신은 어떤 종류의 최소 높이가 필요하고 아마도 일부 패딩을 지정할 수 있지만 이것은 작동합니다.
다른 팁
대신 RichTextbox를 기꺼이 사용하려는 경우 (내 경험에 따라, 많은 기발한 컨트롤이 많은 심술 컨트롤이라는 경우) ContentsResized 이벤트를 사용할 수있어 새로운 필수 크기를 제공 할 수 있습니다.
private void HandleContentsResized(object sender, ContentsResizedEvenetArgs e)
{
int newheight = e.NewRectangle.Height;
}
방금 다른 프로젝트에 대한 레이블 컨트롤을 위해 이것을 썼습니다. 내가 생각하는 어딘가에 코드 프로젝트를 벗어났습니다. 텍스트 상자로 변경하는 것은베이스를 변경하는 것만 큼 간단해야합니다.
public class GrowLabel : Label
{
private bool _growing;
//public bool GrowFontSize { get; set; }
public GrowLabel()
{
AutoSize = false;
//GrowFontSize = false;
}
public override sealed bool AutoSize
{
get { return base.AutoSize; }
set { base.AutoSize = value; }
}
private void ResizeLabel()
{
if (_growing) return;
try
{
_growing = true;
var sz = new Size(Width, Int32.MaxValue);
sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.WordBreak);
Height = sz.Height;
}
finally
{
_growing = false;
}
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
ResizeLabel();
}
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
ResizeLabel();
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
ResizeLabel();
}
}
Adamsane의 게시물은 도움이되었지만 텍스트 상자는 성장하지 않았습니다. 나는 약간의 수정을 할 것입니다. 내 모드는 다음과 같습니다.
class GrowTextBox : TextBox
{
private double m_growIndex = 0.0;
private Timer m_timer;
public GrowTextBox()
{
AutoSize = false;
this.Height = 20;
// Without the timer, I got a lot of AccessViolationException in the System.Windows.Forms.dll.
m_timer = new Timer();
m_timer.Interval = 1;
m_timer.Enabled = false;
m_timer.Tick += new EventHandler(m_timer_Tick);
this.KeyDown += new KeyEventHandler(GrowTextBox_KeyDown);
}
void GrowTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A)
{
this.SelectAll();
}
}
void m_timer_Tick(object sender, EventArgs e)
{
var sz = new Size(Width, Int32.MaxValue);
sz = TextRenderer.MeasureText(Text, Font, sz, TextFormatFlags.TextBoxControl);
m_growIndex = (double)(sz.Width / (double)Width);
if (m_growIndex > 0)
Multiline = true;
else
Multiline = false;
int tempHeight = (int)(20 * m_growIndex);
if (tempHeight <= 20)
Height = 20;
else
Height = tempHeight;
m_timer.Enabled = false;
}
public override sealed bool AutoSize
{
get { return base.AutoSize; }
set { base.AutoSize = value; }
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
m_timer.Enabled = true;
}
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
m_timer.Enabled = true;
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
m_timer.Enabled = true;
}
}
나는 약 10 라인까지의 성공과 함께 아래 코드를 사용하고 있다면 1자가 꺼져 있지만 이것은 나에게 효과적입니다. -7 및 -12와 같은 임의의 숫자에 대해 묻지 마십시오. 패딩과 관련이 있습니다.
private void txbDescription_TextChanged(object sender, EventArgs e)
{
SizeF s = TextRenderer.MeasureText(txbDescription.Text, txbDescription.Font, txbDescription.ClientRectangle.Size, TextFormatFlags.TextBoxControl);
int lines = (int)Math.Ceiling((decimal)Convert.ToInt32(s.Width - 7) / ((decimal)txbDescription.Width - 12));
if (lines == 0)
{
txbDescription.Height = 20;
}
else
{
txbDescription.Height = 20 + (lines - 1) * 13;
}
}
불행히도, 나는 세부 사항을 제공 할 수 없지만 아마도 사용자 정의 구현을 수행해야 할 것입니다.
새로운 텍스트 상자 유형 인 ExpandableTextBox를 도출 한 다음 수작업으로 구현해야합니다.
이것은 또한 당신이 찾고있는 것과 관련이있는 것 같습니다. http://social.msdn.microsoft.com/forums/en-us/winforms/thread/11dfb280-1113-4ddf-ad59-788f78d2995a