将非模态子Windows.Forms.Form添加到主窗体时会出现问题,导致子窗格无法获得焦点

时间:2016-09-25 19:30:55

标签: winforms non-modal

前言(可能会在发布答案后删除)。这是一个我无法在网上找到答案的问题(经过几天的搜索)。我通过试验 - 错误找到了答案,但我并不是特别熟悉主题 - 表格 - 所以我的解决方案可能不是最好的,甚至是正确的。

我使用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"它,所以当我构建,添加和显示非模态孩子时,孩子可以获得焦点?哪里有关于此的文件?上面的代码实际上是正确的方法吗?任何人都可以解释一下发生了什么事吗?

编辑: 事实上,情况比这更复杂。如果孩子非模态形式在显示父母时可见,则父母将是"模态",并且孩子将无法获得焦点。如果子窗体在显示父窗体之前将其所有者设置为父窗体,则在尝试显示父窗体时会抛出异常。我找不到所有这些问题的正确文件。

0 个答案:

没有答案