前言(可能会在发布答案后删除)。这是一个我无法在网上找到答案的问题(经过几天的搜索)。我通过试验 - 错误找到了答案,但我并不是特别熟悉主题 - 表格 - 所以我的解决方案可能不是最好的,甚至是正确的。
我使用Windows Forms创建了一个小应用程序。应用程序执行一些(冗长的)数据处理,它需要第二个单独的窗口来显示(正在进行的)错误。为此,我使用(简单)非模态形式。
结构相当简单:
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()
),所以这可能并不意外,但网上的所有文档和示例都表明a( modal)这样的主对话应该能够打开一个非模态子对话框,并且子对话框应该能够收到焦点。此外,只需确保使用m_infoBox
的某个实例初始化成员数据元素NonModalInfo
,那么行为就不同了:子表单将被赋予焦点,没有问题。从外观来看,在显示m_infoBox
之前使用非空实例初始化mainForm
的情况下,mainForm
似乎显示为非模态(尽管有与ShowDialog()
)一起显示。
我的问题是,为什么我需要确保使用非null实例初始化mainForm
成员m_infoBox
?有没有办法构建mainForm
和" show"它,所以当我构建,添加和显示非模态孩子时,孩子可以获得焦点?哪里有关于此的文件?上面的代码实际上是正确的方法吗?任何人都可以解释一下发生了什么事吗?
编辑: 事实上,情况比这更复杂。如果孩子非模态形式在显示父母时可见,则父母将是"模态",并且孩子将无法获得焦点。如果子窗体在显示父窗体之前将其所有者设置为父窗体,则在尝试显示父窗体时会抛出异常。我找不到所有这些问题的正确文件。