0

前言(可能会在发布答案后被删除)。这是一个我在网上任何地方都找不到答案的问题(经过几天的搜索)。我自己通过试错找到了答案,但我对主题 - 形式并不特别熟悉,所以我的解决方案可能不是最好的,甚至不是正确的。

我使用 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显示 之前使用非空实例初始化的情况下mainFormmainForm似乎显示为非模态(尽管已显示ShowDialog())。

我的问题是,为什么我需要确保mainForm' 的成员m_infoBox是用非空实例初始化的?有什么方法可以构造mainForm和“显示”它,这样当我构造、添加和显示非模态孩子时,孩子可以接收焦点?哪里有这方面的文件?上面的代码实际上是正确的方法吗?谁能解释引擎盖下发生了什么?

编辑:事实上,情况比这更复杂。如果子非模态窗体在显示父级时可见,则父级将是“模态”的,子级将无法获得焦点。如果子窗体在显示父窗体之前已将其所有者设置为父窗体,则在尝试显示父窗体时会引发异常。我找不到关于所有这些问题的像样的文档。

4

0 回答 0