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