回答:
"Shown"イベントを使用できます:MSDN-Form.Shown
「Shownイベントは、フォームが初めて表示されたときにのみ発生します。その後、最小化、最大化、復元、非表示、表示、または無効化して再描画しても、このイベントは発生しません。」
私は時々(ロードで)使用します
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
または
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(「this」以外のインスタンスでイベントを処理する場合は、「this」をフォーム変数に変更します)。
これにより、呼び出しがwindows-formsループにプッシュされるため、フォームがメッセージキューを処理しているときに処理されます。
[リクエストに応じて更新]
Control.Invoke / Control.BeginInvokeメソッドは、スレッドで使用することを目的としており、UIスレッドに作業をプッシュするメカニズムです。通常、これはワーカースレッドなどで使用されます。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メッセージキューにプッシュすることによって行われます。UIスレッドは(ある時点で)メッセージをデキューし、デリゲートを処理し、完了したことをワーカーに通知します。
OK; では、UIスレッドでControl.Invoke / Control.BeginInvokeを使用するとどうなりますか?それは対処します... Control.Invokeを呼び出した場合、メッセージキューでのブロックが即時のデッドロックを引き起こすことを知るのは十分に賢明です。助けにならない...
ただし、Control.BeginInvokeの動作は異なります。UI スレッド上にある場合でも、常にキューに作業がプッシュされます。これは、「すぐに」という簡単な言い方をしますが、タイマーなどの不便さはありません(とにかく同じことをしなければなりません!)。
初回は「AfterLoading」を開始しませんが、
それを登録するだけで次のロードを開始します。
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.
}
私は同じ問題を抱えており、それを次のように解決しました:
メッセージを表示して、2秒後に自動的に閉じたいのですが。そのため、(動的に)単純なフォームとメッセージを表示する1つのラベルを生成し、1500ミリ秒間メッセージを停止して、ユーザーがそれを読む必要がありました。そして、動的に作成されたフォームを閉じます。表示されたイベントは、ロードイベントの後に発生します。だからコードは
Form MessageForm = new Form();
MessageForm.Shown += (s, e1) => {
Thread t = new Thread(() => Thread.Sleep(1500));
t.Start();
t.Join();
MessageForm.Close();
};
これは古い質問であり、いつルーチンを開始する必要があるかによります。null参照例外は必要ないため、最初にnullを確認してから、必要に応じて使用することが常に最善です。それだけであなたは多くの悲しみを救うでしょう。
このタイプの質問の最も一般的な理由は、コンテナーまたはカスタムコントロールタイプが、カスタムクラスの外部で初期化されたプロパティにアクセスしようとするときです。オブジェクトタイプ。これは、クラスが完全に初期化される前、つまりプロパティの設定が完了する前などに実行されていることを意味します。このタイプの質問のもう1つの考えられる理由は、カスタムグラフィックを実行するタイミングです。
form loadイベントに続くコードの実行をいつ開始するかに関する質問に最もよく答えるには、WM_Paintメッセージを監視するか、paintイベント自体に直接フックします。どうして?paintイベントは、フォームの読み込みイベントに関してすべてのモジュールが完全に読み込まれたときにのみ発生します。注:this.visible == trueは、trueに設定されていると常にtrueになるとは限らないため、フォームを非表示にすることを除いて、この目的にはまったく使用されません。
以下は、フォームロードイベントに続いてコードの実行を開始する方法の完全な例です。ペイントメッセージループを不必要に拘束しないことをお勧めします。これにより、ループの外側でコードの実行を開始するイベントを作成します。
using System.Windows.Forms;
名前空間MyProgramStartingPlaceExample {
/// <summary>
/// Main UI form object
/// </summary>
public class Form1 : Form
{
/// <summary>
/// Main form load event handler
/// </summary>
public Form1()
{
// Initialize ONLY. Setup your controls and form parameters here. Custom controls should wait for "FormReady" before starting up too.
this.Text = "My Program title before form loaded";
// Size need to see text. lol
this.Width = 420;
// Setup the sub or fucntion that will handle your "start up" routine
this.StartUpEvent += StartUPRoutine;
// Optional: Custom control simulation startup sequence:
// Define your class or control in variable. ie. var MyControlClass new CustomControl;
// Setup your parameters only. ie. CustomControl.size = new size(420, 966); Do not validate during initialization wait until "FormReady" is set to avoid possible null values etc.
// Inside your control or class have a property and assign it as bool FormReady - do not validate anything until it is true and you'll be good!
}
/// <summary>
/// The main entry point for the application which sets security permissions when set.
/// </summary>
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
#region "WM_Paint event hooking with StartUpEvent"
//
// Create a delegate for our "StartUpEvent"
public delegate void StartUpHandler();
//
// Create our event handle "StartUpEvent"
public event StartUpHandler StartUpEvent;
//
// Our FormReady will only be set once just he way we intendded
// Since it is a global variable we can poll it else where as well to determine if we should begin code execution !!
bool FormReady;
//
// The WM_Paint message handler: Used mostly to paint nice things to controls and screen
protected override void OnPaint(PaintEventArgs e)
{
// Check if Form is ready for our code ?
if (FormReady == false) // Place a break point here to see the initialized version of the title on the form window
{
// We only want this to occur once for our purpose here.
FormReady = true;
//
// Fire the start up event which then will call our "StartUPRoutine" below.
StartUpEvent();
}
//
// Always call base methods unless overriding the entire fucntion
base.OnPaint(e);
}
#endregion
#region "Your StartUp event Entry point"
//
// Begin executuing your code here to validate properties etc. and to run your program. Enjoy!
// Entry point is just following the very first WM_Paint message - an ideal starting place following form load
void StartUPRoutine()
{
// Replace the initialized text with the following
this.Text = "Your Code has executed after the form's load event";
//
// Anyway this is the momment when the form is fully loaded and ready to go - you can also use these methods for your classes to synchronize excecution using easy modifications yet here is a good starting point.
// Option: Set FormReady to your controls manulaly ie. CustomControl.FormReady = true; or subscribe to the StartUpEvent event inside your class and use that as your entry point for validating and unleashing its code.
//
// Many options: The rest is up to you!
}
#endregion
}
}