WPF所有者窗口位于子窗口顶部

aelbi1ox  于 2022-12-19  发布在  其他
关注(0)|答案(5)|浏览(215)

当您单击WPF中的“所有者”窗口而“所有者”窗口在“子”窗口之下时,它是否可能在“子”窗口之上?
下面是调用子窗口示例:

Window2 window = new Window2();
window.Owner = this;
window.Show();

父/所有者窗口将始终位于子窗口下。

9q78igpj

9q78igpj1#

要获得所需的行为,不需要在任何一个窗口上设置所有者。
当然,您必须自己处理关闭任意一个窗口以关闭您想象中的“子”窗口时的逻辑。
可能还有一些其他的逻辑需要你去实现,比如最小化,最大化等等。

6vl6ewon

6vl6ewon2#

本页上的许多答案都涉及 nulling-out部分或全部的Window.Owner属性(non-MainWindow)窗口。虽然这是一个简单易行的修复方法,确实可以单独修复Window重叠的问题,不幸的是,它也抑制了WPF在以下领域中渴望提供的许多有用的应用程序范围的功能:

  • Application激活/停用(通过鼠标点击、桌面Alt-Tab切换等),
  • 正确遵守X1 E0 F1 X性质,并且通常,
  • 有序地清理、处理资源,并在Application关机时退出。

通过指定一个***特殊的不可见窗口***示例作为Application.MainWindow,可以修复Window重叠问题,同时仍然保留这些系统范围的WPF功能。
修改应用程序,使其创建的第一个Window--即分配给Application.MainWindowWindow--是一个特殊的虚拟Window,然后通过将其Visibility设置为Visibility.Hidden或调用Window.Hide()使其不可见。确保你想要的“主”窗口包含你真正的内容,加上所有其他窗口,拥有这个不可见的窗口。
隐藏后,虚拟Window将不会显示在Windows 10任务栏中。您可以根据需要在您认为合适的任何可见窗口上设置Window.ShowInTaskbar属性,以模拟明显的特殊指定。
此方法允许Application中的任何可见窗口位于其他窗口的顶部,同时仍保留WPF功能和行为以用于系统范围的应用激活。(通过点击任何一个窗口,或通过Alt-tab),应用程序的所有窗口一起被带到任何其他桌面应用程序窗口之上,同时仍保留最近的“应用内”Z顺序。还保留了WPF关闭功能,包括根据关闭的不可见MainWindow(或所有其他)正确观察Application.ShutdownMode逻辑。

oewdyzsn

oewdyzsn3#

我遇到了类似的情况,我解决了这个问题,简单地删除业主后,显示窗口。

Window2 window = new Window2();
window.Owner = this;
window.Show();
window.Owner = null;

编辑:有人回复了这个,在看的同时,我决定我要做一个扩展方法。

public static void ShowAsIfChildOf(this Window childWindow, Window parentWindow)
{
  childWindow.Owner = parentWindow;
  childWindow.Show();
  childWindow.Owner = null;
}
blmhpbnm

blmhpbnm4#

请注意,Licht提到的解决方案

Window2 window = new Window2();
window.Owner = this;
window.Show();
window.Owner = null;

在我看来就像

Window2 window = new Window2();
window.Show();

即好像没有设置所有权关系,即当你关闭所有者窗口时,所拥有的窗口不关闭等,并且在希望具有除“所有者窗口永远不能覆盖所拥有的窗口”之外的所有权关系特征时可能不是解决方案。
一旦建立了这种关系,就会表现出以下行为:

  • 如果最小化所有者窗口,则其所有窗口也将最小化。
  • 如果拥有的窗口被最小化,则其所有者不会被最小化。
  • 如果所有者窗口被最大化,则所有者窗口及其所拥有的窗口都将被还原。
  • 所有者窗口永远不能覆盖被拥有的窗口。
  • 未使用ShowDialog打开的所有者窗口不是模式窗口。用户仍然可以与所有者窗口交互。
  • 如果关闭所有者窗口,则其拥有的窗口也将关闭。

在我看来,这里最好的解决方案是Glenn Slayden在下面的链接中描述的带有隐藏的主虚拟窗口的解决方案,尽管如果有一个更简单的解决方案就好了。
https://stackoverflow.com/a/66110288/19683309

waxmsbnn

waxmsbnn5#

不要为子窗口设置Owner,然后在MainWindow中处理OnClosing事件,如下所示:

private void MainWindow_OnClosing(object? sender, CancelEventArgs e)
{
    foreach (var window in Application.Current.Windows)
    {
        if (window is Window appWindow)
        {
            if(appWindow.Equals(Application.Current.MainWindow))
                continue;

            appWindow.Close();
        }
    }
}

相关问题