序文 (回答が投稿された後、後で削除される可能性があります)。これは、オンラインのどこにも答えが見つからなかった質問です (数日間検索した後)。試行錯誤して自分で答えを見つけましたが、主題であるフォームに特に精通していないため、私の解決策が最善ではないか、正しくない可能性さえあります。
Windows フォームを使用して小さなアプリケーションを作成しました。アプリケーションは (時間のかかる) データ処理を行い、(進行中の) エラーを表示するために 2 番目の別のウィンドウが必要です。このために、(単純な) 非モーダル フォームを使用しています。
構造はかなり単純です。
public static class Program
{
[STAThread]
public static int Main(string[] args)
{
MainForm mainForm = new MainForm();
mainForm.showTheForm();
}
}
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
init();
}
private NonModalInfo m_infoBox = null;
//plus a few other data members...
private void init()
{
//initialize some data members and other stuff, etc.
//Then, this critical line:
m_infoBox = new NonModalInfo();
}
public void showTheForm()
{
this.ShowDialog();
}
//private void somecontrol_click(...)
//{
//for(some loop)
//{
// doStuff;
// showInfo("SomeMessage");
// doStuff;
//}
//}
//this method only gets called while the mainForm is showing,
// as, for example, in the somecontrol_click method above
public void showInfo(string msg)
{
if (m_infoBox == null || m_infoBox.IsDisposed)
{
m_infoBox = new NonModalInfo();
}
m_infoBox.updateMessage(msg);
if (this.Visible)
{
if(!m_infoBox.Visible)
{
m_infoBox.Owner = this;
m_infoBox.Show();
}
}
}
}
public partial class NonModalInfo : Form
{
public NonModalInfo()
{
InitializeComponent();
}
//This form has one element, a label called lb_Message.
public void updateMessage(string msg)
{
if (msg != null)
{
lb_Message.Text = msg;
if (Visible)
{
Update();
}
}
}
}
ここでの基本的な考え方は、NonModalInfo
フォームがmainForm
ログやエラー情報をユーザーに表示するために使用されるということです。上記の構造は、私が持っているように、完全に機能します。問題は、上記でコメントした行ですThen, this critical line:
。その行がなければ-これは私が最初にコードを書いた方法です-コードはほとんど機能します:非モーダルフォームが開かれ、表示され、更新されます。問題は、非モーダルフォームがフォーカスを受け取ることができないことです:非モーダルフォームをクリックしてフォーカスを与えると、mainForm
点滅してフォーカスが維持されます。mainForm
非モーダル フォームがフォーカスを受け取ることができないように、この動作はモーダルで開かれたときに期待されるものとまったく同じです。
現在、mainForm
はモーダルで開かれているShowDialog()
ため ( )、おそらくこれは予期しないことではありませんが、Web 上のすべてのドキュメントと例は、このような (モーダル) メイン ダイアログが非モーダルの子ダイアログを開くことができるはずであることを示しています。子ダイアログがフォーカスを受け取ることができる必要があります。さらに、メンバー データ要素m_infoBox
が のインスタンスで初期化されていることを確認するだけでNonModalInfo
、動作が異なります。子フォームにフォーカスが与えられますが、問題ありません。外観から、m_infoBox
を表示する前に が null 以外のインスタンスで初期化されている場合、 は非モーダルとして表示されているように見えます ( で表示されているにもかかわらずmainForm
) 。mainForm
ShowDialog()
mainForm
私の質問は、のメンバーm_infoBox
が null 以外のインスタンスで初期化されていることを確認する必要があるのはなぜですか? mainForm
非モーダルな子を構築、追加、表示するときに、子がフォーカスを受け取ることができるように、それを構築して「表示」する方法はありますか? これに関するドキュメントはどこにありますか? 上記のコードは実際にこれを行う正しい方法ですか? ボンネットの下で何が起こっているのか誰か説明できますか?
編集: 実際、状況はこれよりも複雑です。親が表示されているときに子の非モーダル フォームが表示されている場合、親は「モーダル」になり、子はフォーカスを受け取ることができません。親が表示される前に子フォームの所有者が親に設定されている場合、親を表示しようとすると例外がスローされます。これらすべての問題に関する適切なドキュメントが見つかりません。