Запуск кода в событии Load
или OnLoad
часто является худшим решением.
Если вы хотите запустить код один раз после загрузки формы, вы можете использовать событие Shown
, в противном случае форма выглядит запоздалой и не реагирует на ваши действия, если у вас есть долго выполняющийся код (элементы управления отображаются один за другим).
Если вы действительно хотите запустить код после дочернего конструктора, но до события загрузки, переопределение OnHandleCreated - ваш лучший выбор.
Однако: остается (по крайней мере) одна вещь, которая не будет работать. У меня был базовый класс формы, который устанавливал определенную начальную позицию / размер независимо от того, что определяла дочерняя форма. Каждое усилие, которое я делал, терпело неудачу, или форма была видна в неправильном местоположении в течение доли секунды. Вот как я это решил:
public class MyForm : Form
{
private Size defaultSize;
public MyForm()
{
InitializeComponent();
this.defaultSize = this.Size;
this.fireOnBeforeLoad = true;
}
public new void ResumeLayout(bool performLayout)
{
base.ResumeLayout(performLayout);
if (fireOnBeforeLoad)
{
fireOnBeforeLoad = false;
OnBeforeLoad();
}
}
protected virtual void OnBeforeLoad()
{
form.WindowState = FormWindowState.Normal;
form.Size = defaultSize;
form.FormBorderStyle = FormBorderStyle.FixedDialog;
var area = Screen.FromControl(form).WorkingArea;
form.Size = defaultSize;
form.Location = new System.Drawing.Point(
(int)(area.Width - form.Width) / 2,
(int)(area.Height - form.Height) / 2);
}
}
Вот сложная часть: после того, как вы установили размер, он каким-то образом восстанавливается в некоторой точке процесса загрузки. То же самое происходит, если вы звоните Screen.FromControl(form)
. Я полагаю, потому что Screen.FromControl
в конечном итоге вызывает Screen.FromHandle
, и это приведет к созданию дескриптора. Но я полагаю, что он делает что-то еще, потому что, если я выполню приведенный выше код в методе OnHandleCreated
(после вызова base.OnHandleCreated
, конечно), он не получит желаемый результат. Из-за этого я снова установил размер после Screen.FromControl
, последняя строка просто центрирует форму на экране.