gpt4 book ai didi

c# - WPF应用程序类和主窗口初始化

转载 作者:可可西里 更新时间:2023-11-01 10:34:39 25 4
gpt4 key购买 nike

我有

public static int WindowCounter = 0;

[STAThread]
public static void Main()
{
ShowBeforeApplicationCreation();
//ShowAfterApplicationCreation();
}

public static void ShowBeforeApplicationCreation()
{
ShowWindow();
ShowWindow();
ShowWindow();
var app = new Application();
app.Run();
}

public static void ShowAfterApplicationCreation()
{
var app = new Application();
ShowWindow();
ShowWindow();
ShowWindow();
app.Run();
}

public static void ShowWindow()
{
var window = new Window { Title = string.format("Title{0}", WindowCounter++) };
window.Show();
}

如果运行如图所示的代码,然后关闭任何一个窗口,它将关闭所有窗口。如果我切换到已注释掉的内容,那么哪个窗口将导致所有窗口关闭(大多数时候是最后一个窗口)似乎是随机的。

应用程序如何确定哪个窗口将导致进程关闭?

该窗口是“主”窗口吗?

让我们将关闭进程的窗口定义为OwningWindow(希望该名称在此上下文中不会重载)。如何确保显示的第一个窗口是OwningWindow?

最后一个问题是我的主要问题。我不想打开其他辅助窗口,让用户关闭主窗口,并使进程继续运行。还是我必须让我想要成为OwningWindow的窗口的后续窗口成为子窗口?

最佳答案

How is the Application deciding which window will cause the process to close?



默认情况下,当所有打开的窗口都关闭时, Application类将退出 Run()方法(因此将退出整个过程)。但是,根据您的代码示例,似乎有些皱纹: Application类不考虑在其自身创建之前打开的任何窗口。如果您不告诉它任何窗口(即通过传递对 Run()方法的引用),则任何关闭窗口的操作都会导致 Run()方法退出,因为 Application类的确看到了窗口的关闭,但认为存在在此过程中没有 window 。

Is that window the "main" window?



默认情况下,“主”窗口是在 AppDomain中实例化的第一个窗口。您可以随时通过设置 MainWindow对象的 Application 属性来覆盖它。

自然地,如上所述, Application对象无法在创建其自身之前看到创建的窗口。一个异常(exception):如果将窗口传递给 Run()方法,则即使该窗口是在 MainWindow对象之前创建的,也可以成为 Application。如果所有窗口都在 Application之前创建,并且您没有将对任何这些窗口的引用传递给 Run()方法,则根本没有主窗口。

如果您要确定性地分配一个窗口以使该过程在关闭窗口时退出,则一种选择是将其传递给 Application.Run()方法。例如:
class Program
{
public static int WindowCounter = 0;
private static Window _firstWindow;

[STAThread]
public static void Main()
{
ShowBeforeApplicationCreation();
}

public static void ShowBeforeApplicationCreation()
{
ShowWindow();
ShowWindow();
ShowWindow();
var app = new Application();
app.Run(_firstWindow);
}

public static void ShowWindow()
{
var window = new Window { Title = string.Format("Title{0}", WindowCounter++) };
window.Show();
_firstWindow = _firstWindow ?? window;
}
}

就是说, Application.ShutdownMode的默认值为 ShutdownMode.OnLastWindowClose,因此,如果不做其他任何事情,则在关闭最后一个窗口之前,程序不应关闭。这仅仅是因为该类似乎没有注意到实例化之前打开的窗口(显然,它对窗口的实际创建有反应,而不是在启动时在打开的窗口中进行搜索)。

显然,在调用 Application.Run()之前创建窗口会混淆该方法。似乎认为如果关闭了任何窗口,都不会再打开。如果将其传递给其中一个窗口的引用,则在关闭该窗口之前,它不会返回,该窗口是它“知道”的唯一窗口;其他窗口的关闭都将被忽略,因为它知道的一个窗口仍处于打开状态。

(对于它的值(value),在我的测试中,在所有窗口均在 Application对象之后创建的情况下,直到所有窗口都关闭,程序才会退出。这与上述观点一致,即 Application类正确地记录了所有已创建的窗口,并且/或在其本身创建后显示)。

恕我直言,最好的方法是不要混淆该方法。它无法正确处理在创建 Application对象之前显示的窗口。所以,不要那样做。确保仅在创建 Application后创建所有窗口。如果您要关闭的特定行为与默认的 ShutdownMode.OnLastWindowClose行为不同,则应足够简单地实现。

就像将 ShutdownMode属性设置为其他内容一样简单。例如, ShutdownMode.OnMainWindowClose。在这种情况下,您当然需要确保某个窗口是主窗口,否则该过程将根本不会退出。您可以通过使用默认行为(即,将主窗口创建为第一个窗口,但在创建 Application对象之后),显式设置 MainWindow属性,甚至将窗口引用传递给已创建的 Run()方法来执行此操作 Application对象之前的所有窗口。

Let's define the window that closes the process as the OwningWindow (hopefully that name isn't overloaded in this context). How can I ensure that the first window shown is the OwningWindow?



通过以上讨论,您可能可以自己回答这个问题。 :)

首先,“拥有窗口”实际上是 MainWindow。但是,默认情况下, Application.Run()方法仅在所有窗口(它知道的)都关闭时返回。只是通过从 Application方法隐藏一些窗口,似乎某些“拥有窗口”负责关闭程序(在默认的 ShutdownMode方案中)。

实际上,如果仅在关闭某些特定窗口时才关闭程序,那么正确的方法是确保正确设置 MainWindow,并将 Application.ShutdownMode设置为 ShutdownMode.OnMainWindowClose值。这样,您就可以对WPF完全清楚地了解所需的确切行为,即使您在创建 Window对象之前进行了类似创建 Application对象的怪异操作,也没有机会将其弄乱。 :)

关于c# - WPF应用程序类和主窗口初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33768773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com