プロセスのステータスに関する情報を表示する情報フォームがあります。このフォームは、ユーザーがプロセスの実行を指示するメイン フォームの上に表示されます。現在、この情報フォームを別のスレッドで実行していますが、メイン フォームの上に貼り付けることができません。タスクバーの右下隅にある [デスクトップの表示] ボタンをクリックして、タスクバーからアプリケーションを復元しようとすると、情報フォームが表示されません。この情報フォームをメイン フォームに貼り付けたままにするにはどうすればよいですか?
3 に答える
これがきれいな方法かどうかはわかりませんが、うまくいきます!
private void Form1_Load(object sender, EventArgs e)
{
this.Resize += OnResize;
}
private void OnResize(object sender, EventArgs eventArgs)
{
if (form2running && form != null && (WindowState == FormWindowState.Maximized || WindowState == FormWindowState.Normal))
{
form.Invoke((MethodInvoker)(() => form.WindowState = FormWindowState.Normal));
}
}
private bool form2running = false;
private Form form;
private void button2_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(ShowNewForm);
}
private void ShowNewForm(object o)
{
form2running = true;
form = new Form2();
Application.Run(form);
form2running = false;
}
すべての形式のアプリケーションは、単一のUIスレッドで実行する必要があります。バックグラウンドで何らかの操作を実行する場合は、バックグラウンドスレッドを使用します(たとえば、BackgroundWorkerを介して)。バックグラウンドスレッドから新しいデータが到着したら、情報フォームのUIを更新するだけです。
Windowsフォームのマルチスレッドを見てください
winformsコントロールはスレッドセーフではないことに注意してください。
Windowsフォームコントロールへのアクセスは、本質的にスレッドセーフではありません。コントロールの状態を操作するスレッドが2つ以上ある場合は、コントロールを強制的に不整合な状態にすることができます。競合状態やデッドロックなど、他のスレッド関連のバグも発生する可能性があります。コントロールへのアクセスがスレッドセーフな方法で行われるようにすることが重要です。
情報フォームを作成して別のスレッドで初期化することはできますが、それをメイン スレッドで表示する必要があります。通常、別々のスレッドで実行されている 2 つのフォーム間で操作することはできません。
BackgroundWorker クラスを使用してタスクを実行することを検討してください。