Я создал пользовательский элемент управления, который содержит TabControl с 2 TabPages.Положение дочерних элементов управления на обеих вкладках TabPage адаптируется программно в событии Layout
пользовательского элемента управления.
Проблема заключается в том, что 2-я TabPage еще не была нарисована при вызове события, и поэтому эта TabPage имеетнеправильный размер и размер клиента.
Как я могу обойти это?
Я пробовал цикл с var oHandle = tabpage.Handle
и tabctrl.SelectedTab = each tabpage
уже для принудительного создания TabPages, но это не помогло.
РЕДАКТИРОВАТЬ # 1
Я обнаружил первую «ошибку», которая наблюдается в конструкторе VS:
Когда вы перетаскиваете TabControl
на форму и затем изменяете размерэто в Designer, размер видимого в данный момент TabPage
обновляется.Но размеры всех других вкладок не являются;они остаются неизменными до тех пор, пока не будут внесены какие-либо дополнительные изменения в какой-либо элемент управления (проверено!).
Я допускаю, что эта ситуация довольно необычна, поэтому размеры обычно обновляются, но, тем не менее, на мой взгляд, это ошибка дизайна в TabControl
.
Этот недостаток дизайна становится очень актуальным, когда во время выполнения изменяется размер TabControl!Вот минимальный пример для воспроизведения (без UC, просто TabControl в форме):
Form1.cs:
public Form1 ()
{
InitializeComponent ();
Debug.Print ("ctor before resize");
Debug.Print ("TC: " + tabControl1.Size);
Debug.Print ("T1: " + tabPage1.Size);
Debug.Print ("T2: " + tabPage2.Size);
tabControl1.Size = tabControl1.Size + new Size (10, 10);
Debug.Print ("ctor after resize");
Debug.Print ("TC: " + tabControl1.Size);
Debug.Print ("T1: " + tabPage1.Size);
Debug.Print ("T2: " + tabPage2.Size);
}
private void Form1_Load (object sender, EventArgs e)
{
... same as ctor, prints adapted ("load before/after resize)
}
private void Form1_Layout (object sender, LayoutEventArgs e)
{
Debug.Print ("Layout");
}
private void button1_Click (object sender, EventArgs e)
{
... same as ctor, prints adapted ("button before/after resize)
}
Form1.Designer.cs: (удалены несущественные части)
private void InitializeComponent ()
{
this.tabControl1 = new System.Windows.Forms.TabControl ();
this.tabPage1 = new System.Windows.Forms.TabPage ();
this.tabPage2 = new System.Windows.Forms.TabPage ();
this.button1 = new System.Windows.Forms.Button ();
this.tabControl1.SuspendLayout ();
this.SuspendLayout ();
//
this.tabControl1.Controls.Add (this.tabPage1);
this.tabControl1.Controls.Add (this.tabPage2);
this.tabControl1.Size = new System.Drawing.Size (300, 120);
//
this.tabPage1.Size = new System.Drawing.Size (292, 91);
//
this.tabPage2.Size = new System.Drawing.Size (292, 91);
//
this.button1.Click += new System.EventHandler (this.button1_Click);
//
this.AutoScaleDimensions = new System.Drawing.SizeF (96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size (384, 262);
this.Controls.Add (this.tabControl1);
this.Controls.Add (this.button1);
this.Load += new System.EventHandler (this.Form1_Load);
this.tabControl1.ResumeLayout (false);
this.ResumeLayout (false);
}
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.Button button1;
Отладочные отпечатки:
ctor before resize
TC: {Width=300, Height=120}
T1: {Width=292, Height=91}
T2: {Width=292, Height=91}
Layout
Layout
ctor after resize
TC: {Width=310, Height=130}
T1: {Width=292, Height=91} (wrong)
T2: {Width=292, Height=91} (wrong)
Load before resize
TC: {Width=310, Height=130}
T1: {Width=302, Height=101} (now correct because updated after ctor)
T2: {Width=302, Height=101} (now correct because updated after ctor)
Layout
Layout
Load after resize
TC: {Width=320, Height=140}
T1: {Width=312, Height=111} (correct because visible)
T2: {Width=302, Height=101} (wrong again)
Layout
(TabPage1 selected, TabPage2 is not updated)
button before resize
TC: {Width=320, Height=140}
T1: {Width=312, Height=111}
T2: {Width=302, Height=101} (still wrong: TabPage2 HAS NOT BEEN UPDATED WHILE THE UI-THREAD WAS IDLE)
Layout
Layout
button after resize
TC: {Width=330, Height=150}
T1: {Width=322, Height=121}
T2: {Width=302, Height=101} (even more wrong)
(TabPage1 selected, TabPage2 is not updated)
button before resize
TC: {Width=330, Height=150}
T1: {Width=322, Height=121}
T2: {Width=302, Height=101} (still wrong)
Layout
Layout
button after resize
TC: {Width=340, Height=160}
T1: {Width=332, Height=131}
T2: {Width=302, Height=101} (again more wrong)
(TabPage2 selected, now TabPage1 is not updated)
button before resize
TC: {Width=340, Height=160}
T1: {Width=332, Height=131}
T2: {Width=332, Height=131} (now correct because visible)
Layout
Layout
button after resize
TC: {Width=350, Height=170}
T1: {Width=332, Height=131} (now wrong)
T2: {Width=342, Height=141} (still correct because visible)
Исходя из этого поведения, единственное решение, которое у меня сейчас есть, - это вызов функции UpdateLayout()
моего UC при каждом вызове tabControl1_SelectedIndexChanged (..)
.
РЕДАКТИРОВАНИЕ # 2
«Решение» Редактирования # 1 не работает, потому что:
Если TabPages имеют небольшую ширину, элементы управления на страницах расположены вертикально, что приводит кбольшая высота соответствующей вкладки.Общая высота UC зависит от высоты TabControl, высота которого зависит от всех TabPages, поэтому UpdateLayout()
должен иметь правильные размеры всех TabPages, иначе высота UC изменится позже, когда будет выбрана другая вкладка, ноэто должно быть правильно уже во время разработки.