【问题标题】:What's the difference between Application.Run() and Form.ShowDialog()?Application.Run() 和 Form.ShowDialog() 有什么区别?
【发布时间】:2011-01-19 20:20:29
【问题描述】:

在我的应用程序中,如果登录成功,我想先显示登录表单,然后显示主表单。目前我正在这样做:

var A = new LoginForm();
if ( A.ShowDialog() == DialogResult.OK )
    Application.Run(new MainForm());

但后来我开始怀疑 - Application.Run() 的意义何在?为什么不只做(new MainForm()).ShowDialog() 呢?有什么不同?实现我想要的正确方法是什么?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    Application.Run(Form) 在当前线程上启动一个消息循环并显示指定的表单。消息循环使表单能够接收 Windows 消息(例如,按键、鼠标单击、绘制无效),以使其显示为响应式并与用户进行交互。当您在 Form 实例上调用 ShowDialog() 时,它实际上会执行类似的操作并为已调用 ShowDialog 的表单创建模式消息循环。

    这两个调用没有太大区别。 Application.Run 确实添加了一些额外的事件处理,使您能够在主窗体关闭时对资源进行一些整理(请参阅Application.ThreadExit)。

    推荐的启动 WinForms 应用程序的方法是使用Application.Run,但我怀疑这更像是一种约定而不是规则。使用Application.Run 的最大原因是如果你想打开多个非模态表单。你可以这样做:

    new Form().Show();
    new Form().Show();
    Application.Run();
    

    您无法使用ShowDialog() 方法实现此目的,因为其中一种形式必须是模态的。


    关于你的问题是如何显示登录表单,如果登录成功则显示主表单,我认为你所拥有的很好:

    if (new LoginForm().ShowDialog() == DialogResult.OK)
    {
        Application.Run(new MainForm());
    }
    

    另一种方法是自己进行管道检查,如果登录成功,则在LoginForm 的关闭事件中打开MainForm 的实例。

    【讨论】:

    • 那么,这意味着您可以在两个表单的同一线程上拥有一个消息循环,同时能够分别处理这三个表单?
    【解决方案2】:

    来自 MSDN:

    此方法添加一个事件处理程序到 Closed 的 mainForm 参数 事件。事件处理程序调用 ExitThread 清理 应用。

    http://msdn.microsoft.com/en-us/library/ms157902.aspx

    【讨论】:

    • 这是唯一值得注意的区别吗?我检查了反射器,似乎在幕后还有很多事情发生,具体取决于调用的是哪个。肯定有一些更细微的差异,虽然我不能说是什么 - 反映的代码非常神秘。
    • 我刚找到一个疯狂的,我在谷歌搜索时到达这里,看看是否有人能解释原因:我今天花了大约一个小时工作试图弄清楚为什么 this.Hide() 和这个.Visible = false,在我的表单上,两者实际上都关闭了表单而不是隐藏它。我完全感到困惑。显然有一些区别 - 完全可复制! - form.ShowDialog() 执行此操作,但 Application.Run() 执行预期操作。那是怎么回事? (我猜这个想法是,因为它是模态的,如果它没有显示,它假设你想关闭它。)
    【解决方案3】:

    从我的测试中,我注意到了这个主要区别:

    使用Application.Run时,表单的关闭按钮(红色X)返回DialogResult.None;但是,当使用 ShowDialog 时,关闭按钮会产生 DialogResult.Cancel。

    这对你来说很重要吗?在我的代码中,我正在测试 DialogResult.Cancel 以确定我的应用程序的退出代码。当红色 X 用于关闭表单时,它被打破了。我现在测试 DialogResult.OK 以指示成功退出。

            return myForm.DialogResult == DialogResult.OK ? 0 : 1;
    

    【讨论】:

    • 这是因为 Application.Run 使用 Form.Show()
    【解决方案4】:

    一个关键的区别是 ShowDialog 通常是一个模态对话框。如果您想创建一个用户友好的工具集,您不会希望它由模式对话框组成。

    此外,Application.Run() 接受的不仅仅是表单。它有一些重载。

    至于你的申请,我认为这并不重要。 Application.Run 对我来说很有意义,因为它表示您的实际应用程序的开始。

    【讨论】:

    • 既然是我的主窗体,是不是Modal Dialog也没关系吧?
    【解决方案5】:

    documentation of the overload

    public static void Run(
        ApplicationContext context );
    

    有一个很好的例子,它采用不同的方法,也涉及两种形式。

    【讨论】:

    • 好提示。不幸的是,当我使用 WinCE 时,它对我没有帮助。
    【解决方案6】:

    对于差异的更具体示例:

    如果您的主表单是 MDI 表单,则单击关闭按钮(右上角的“x”或 Alt-F4)时的行为会有所不同,具体取决于您用于显示表单的方法。

    使用Application.Run(mainForm),子窗体的关闭事件运行,然后主窗体的关闭事件运行。

    mainForm.ShowDialog,主窗体的关闭事件运行,子窗体的关闭事件不运行。

    【讨论】:

      【解决方案7】:

      Application.Run() 用于启动应用程序,MainForm 是应用程序的一部分,MainForm()).ShowDialog() 仅用于显示它。

      Application.Run() 是您的应用程序的entry point。与 Main() 方法相同,用于某些类或 ApplicationStart() 用于 WebApplication

      Application.Run() 有不同的重载,其中之一是不带参数的。该方法在没有初始表单的情况下启动应用程序。

      【讨论】:

      • 那么就我应该选择哪一个而言,这意味着什么?到目前为止,在我看来,这两种方式都很好。但肯定有一些细微的差别吧?
      【解决方案8】:

      从我的测试中,我注意到使用带有 DialogResult 的 Application.Run 按钮不会关闭表单(未点击 OnFormClosing)与 ShowDialog 相比,其中带有 DialogResult 的按钮点击 OnFormClosing 并关闭表单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-02
        • 2011-12-12
        • 2010-09-16
        • 2012-03-14
        • 2012-02-06
        • 2011-02-25
        • 2011-11-22
        相关资源
        最近更新 更多