У меня есть записи в моем приложении. NET WinForms, которое я выкладываю с улучшенными элементами управления TextBox на панелях, когда записи доступны для редактирования, но я установил для TextBoxes значение ReadOnly, когда записи не доступны для редактирования. При нажатии кнопки «Сохранить» на редактируемой записи текст сохраняется в базе данных, а затем отображается как недоступная для редактирования запись (до нажатия кнопки «Изменить»). Пожалуйста, смотрите следующий снимок экрана:
Как вы можете надеяться, первая запись не редактируется, а вторая есть. У меня проблема в том, что я хотел бы, чтобы TextBox увеличивался по высоте, если текст слишком большой, чтобы уместиться. Кажется, что TextBox делает WordWrap, но он показывает только одну строку текста или только первые две. Внизу всегда что-то обрезается.
Я просмотрел несколько других постов на этом сайте, в том числе, в частности, Расширяемый WinForms TextBox .
Вот пример код для панели:
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
...
Field1 = new ExpandoField { Multiline = true, WordWrap = true };
Field1.Location = new System.Drawing.Point(42, 3);
if (CanEdit)
{
Field1.BackColor = System.Drawing.Color.White;
Field1.TabIndex = 20;
}
else
{
((ExpandoField) Field1).ReadOnly = true;
Field1.ForeColor = System.Drawing.Color.FromArgb(0, 50, 0);
Field1.BackColor = System.Drawing.Color.Snow;
Field1.TabIndex = 0;
Field1.TabStop = false;
}
Field1.Text = Text1;
Field1.Dock = DockStyle.None;
Field1.Size = new System.Drawing.Size(538 - 25, 34);
Field1.MinimumSize = Field1.Size;
Field1.AutoSize = true;
Controls.Add(Field1);
Как видите, для панели AutoSize установлено значение true. Код для Field2 похож на Field1.
ExpandoField основан на примере кода, который я видел по ответу dstran в Расширяемая WinForms TextBox . Казалось, это наиболее полная реализация предложения, отмеченного как ответ на этот пост. Вот код:
class ExpandoField : TextBox
{
private double m_growIndex = 0.0;
private Timer m_timer;
public ExpandoField()
{
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(ExpandoField_KeyDown);
}
void ExpandoField_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 System.Drawing.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;
}
}
Это, очевидно, не совсем работает. У меня установлена панель AutoSize, но она не растет для размещения второго TextBox. Кроме того, мне нужно каким-то образом положить sh второй TextBox вниз, когда первый растет. Есть ли у панели хороший способ узнать, когда ExpandoField получает событие OnSizeChanged? Похоже, что в результате роста этой панели остальная часть списка панелей должна быть перерисована в более низких местах. Я не уверен, как заставить этот каскадный эффект работать правильно ...
Я также думаю, что использование таймера кажется неэффективным kluge ...
Я все еще учусь WinForms. Есть какой-то хорошо продуманный способ, которым я могу получить поведение, которое я хочу? Есть ли какое-то событие, которое я могу уловить, когда происходит WordWrap (или когда текст превышает размер TextBox)? Это позволило бы мне изменить размер TextBox. И как TextBox сообщает панели, что она изменилась? Нужно ли вызывать обработчик OnSizeChanged для родительской панели? Нужно ли панели вызывать обработчик OnSizeChanged для родительского списка?
Есть предложения?