Как выполнить код ПОСЛЕ загрузки формы?
В .NET у Windows Forms есть событие, которое запускается перед загрузкой формы (Form.Load), но соответствующее событие не запускается ПОСЛЕ загрузки формы. Я хотел бы выполнить некоторую логику после загрузки формы.
Может ли кто-нибудь посоветовать решение?
Ответы
Ответ 1
Вы можете использовать событие "Показывать": MSDN - Form.Shown
"Событие Shown отображается только при первом отображении формы, а затем минимизация, максимизация, восстановление, скрытие, показ или недействительность и перерисовка не повысят это событие".
Ответ 2
Я иногда использую (в Load)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
или
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(измените "this" на переменную формы, если вы обрабатываете событие на экземпляре, отличном от "this").
Это вызывает вызов в цикле окон, поэтому он обрабатывается, когда форма обрабатывает очередь сообщений.
[обновлено по запросу]
Методы Control.Invoke/Control.BeginInvoke предназначены для использования с поточной обработкой и являются механизмом для работы с потоком пользовательского интерфейса. Обычно это используется рабочими потоками и т.д. Control.Invoke выполняет синхронный вызов, где - как Control.BeginInvoke выполняет асинхронный вызов.
Обычно они будут использоваться как:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
Он делает это, нажимая сообщение в очередь сообщений Windows; поток пользовательского интерфейса (в какой-то момент) отменяет очередь сообщения, обрабатывает делегат и сигнализирует работнику, что он завершен... пока что так хорошо; -p
OK; так что произойдет, если мы будем использовать Control.Invoke/Control.BeginInvoke в потоке пользовательского интерфейса? Он справляется... если вы вызываете Control.Invoke, достаточно разумно знать, что блокировка в очереди сообщений вызовет немедленный тупик, поэтому, если вы уже находитесь в потоке пользовательского интерфейса, он просто запускает код немедленно... так что не помогает нам...
Но Control.BeginInvoke работает по-другому: он всегда подталкивает работу к очереди, даже если мы уже находимся в потоке пользовательского интерфейса. Это действительно простой способ сказать "через мгновение", но без неудобства таймеров и т.д. (Что все равно придется делать одно и то же в любом случае!).
Ответ 3
У меня была та же проблема, и я решил ее следующим образом:
На самом деле я хочу показать сообщение и закрыть его автоматически через 2 секунды. Для этого мне пришлось сгенерировать (динамически) простую форму и одну метку с сообщением, остановить сообщение за 1500 мс, чтобы пользователь его прочитал. И Закрыть динамически созданная форма. Отображается событие После события загрузки. Итак, код
Form MessageForm = new Form();
MessageForm.Shown += (s, e1) => {
Thread t = new Thread(() => Thread.Sleep(1500));
t.Start();
t.Join();
MessageForm.Close();
};
Ответ 4
Вы также можете попробовать поместить свой код в активированное событие формы, если хотите, чтобы это произошло, только когда форма активирована. Вам нужно будет поставить логическую "выполнил" проверку, хотя если она должна запускаться только при первой активации.
Ответ 5
В первый раз он НЕ запускает "AfterLoading",
Он просто зарегистрирует его, чтобы начать NEXT Load.
private void Main_Load(object sender, System.EventArgs e)
{
//Register it to Start in Load
//Starting from the Next time.
this.Activated += AfterLoading;
}
private void AfterLoading(object sender, EventArgs e)
{
this.Activated -= AfterLoading;
//Write your code here.
}
Ответ 6
Вы можете закрыть форму после выполнения.
//YourForm.ActiveForm.Close();
LoadingForm.ActiveForm.Close();