【问题标题】:Unexpected behaviour of System.Windows.Window.ShowDialog() when no other windows are open. Any idea why?没有其他窗口打开时 System.Windows.Window.ShowDialog() 的意外行为。知道为什么吗?
【发布时间】:2011-08-04 17:07:48
【问题描述】:

当我的 WPF MVVM 应用程序试图在主窗口启动之前显示两个连续的错误对话框窗口时,我发现了这一点(付出了一些努力):确定第一个窗口后,应用程序进入一个循环,第二个错误对话框从来没有出现过。

我解决了这个问题,但我希望有人能告诉我为什么会这样。

看起来,如果没有非模态打开的窗口,如果一个对话框窗口已经关闭,所有新的对话框窗口都立即关闭,不显示。

它很容易重现,所以这里有一些非常自负的代码来说明这个问题。这段代码是完整的,所以只用这个,你应该可以重现它。

为对话框窗口创建一个 Window 控件,没有代码,只有以下 XAML:

<Window x:Class="ForumExampleShowDialogIssue.OKDialogWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="OKDialogWindow" Height="300" Width="300">
<StackPanel>
    <TextBlock Text="This is a Window with a single button. The button is set to Cancel, so it closes the window."
               TextWrapping="Wrap"
               Margin="5"/>
    <Button Content="OK" IsCancel="True" IsDefault="True"
            Margin="5"/>
</StackPanel>

接下来,使用标准 WPF App 类,在 XAML 中没有任何新内容,但在后面的代码中包含以下内容:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    OKDialogWindow alwaysOpen = new OKDialogWindow();
    alwaysOpen.Show();

    while (true)
    {                
        OKDialogWindow dialogWindow = new OKDialogWindow();
        Console.WriteLine("Before show");
        dialogWindow.ShowDialog();
        Console.WriteLine("After show");
    }
}

删除 MainWindow.XAML(如果存在),并从 App.XAML 标头中删除对它的引用。

运行。 (程序,不像 Forest)。

这按预期工作。 alwaysOpen 窗口保持打开状态,而一个接一个的 dialogWindow 实例以对话模式出现,在单击 OK 时关闭,然后显示下一个.

但是,当您将 OnStartup 更改为以下内容时,这会中断:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    while (true)
    {                
        OKDialogWindow dialogWindow = new OKDialogWindow();
        Console.WriteLine("Before show");
        dialogWindow.ShowDialog();
        Console.WriteLine("After show");
    }

}

当没有持续打开的窗口时,第一个对话窗口是唯一有效的。之后,无数的“演出前”和“演出后”消息被打印到控制台,但没有出现新的对话框窗口 - 它们一显示就自动关闭。

这肯定不是预期的行为吗?你得到同样的结果吗?知道为什么会这样吗?

【问题讨论】:

  • 您的 App 类的默认构造函数 public App() { } 是否有 this.InitializeComponent(); 调用?因为它的及时初始化对于顺序 ShowDialog() 调用的工作非常重要......我猜在你的第一个 ShowDialog 自动成为应用程序上下文中的主窗口,并且随后的 ShowDialog 调用不起作用,因为假设的“MainWindow”到那时关闭。 ...

标签: wpf dialog window modal-dialog showdialog


【解决方案1】:

这是预期的行为。

  • 默认情况下,第一个打开的窗口是 MainWindow。
  • 默认情况下,列表中的唯一窗口成为 MainWindow(如果要删除其他窗口)。
  • 应用程序类被设计为在没有窗口存在时退出 窗口列表。

检查这个: http://www.ageektrapped.com/blog/the-wpf-application-class-overview-and-gotcha/

【讨论】:

  • 谢谢,这是一个很好的链接。我想我是他所说的“天真的开发者”,因为这正是我所做的。
  • 我记得几天前读过类似的代码。无论如何,很高兴链接有所帮助。
【解决方案2】:

解决

您可以转到App.xaml 文件并将其添加到根&lt;Application&gt; 节点中:

ShutdownMode="OnExplicitShutdown"

这意味着即使您关闭了所有窗口,应用程序仍然会运行,直到您显式调用 InvokeShutdown() 方法。 ShutdownMode的默认值为OnMainWindowClose

说明

在您的第一个 sn-p 中,您首先创建一个永不关闭的窗口。这是MainWindow,它永远不会关闭。因此Application 永远不会关闭。但是在您的第二个 sn-p 中,您的 MainWindow 是您创建的第一个对话框。应用程序将在窗口关闭后立即关闭。 Application 关闭后,您的其他对话框将永远不会显示,对吧?

参见 MSDN:https://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多