模态对话框没有显示在其他窗口的顶部

时间:2011-06-20 21:08:45

标签: wpf showdialog

我正在使用Window.ShowDialog()在我的WPF(MVVM)应用程序中打开一个模态窗口,但它允许我使用Windows任务栏(Windows 7)导航到其他窗口。

考虑一下: 我在我的应用程序中打开了3个非模态窗口。现在其中一个使用Window.ShowDialog()打开一个模态窗口。我还将Application.MainWindow设置为模态窗口的所有者。这是因为我使用MVVM消息传递而消息处理程序打开一个新窗口集中在App.xaml.cs。窗口打开模态 - 没有问题。但是,Windows 7允许我从任务栏切换到其他应用程序窗口。这导致了模态窗口落在另一个窗口后面的情况,我不喜欢这个窗口。

只要我打开模态,我就无法在其他窗口上执行任何操作,但如果模态窗口始终保持在顶部,只要打开它就会很好。有没有办法在模态打开时禁用任务栏切换?仅供参考 - 从应用程序启动的所有打开的窗口在任务栏上显示为单独的条目。

提前致谢!

5 个答案:

答案 0 :(得分:59)

没有任何代码可以基于此,但听起来你已经在你创建的Window上留下了一些属性,并期望ShowDialog应用额外的“对话框”语义:

Window window = new Window()
{
    Title = "Modal Dialog",
    ShowInTaskbar = false,               // don't show the dialog on the taskbar
    Topmost = true,                      // ensure we're Always On Top
    ResizeMode = ResizeMode.NoResize,    // remove excess caption bar buttons
    Owner = Application.Current.MainWindow,
};

window.ShowDialog();

答案 1 :(得分:11)

只需将Window的owner属性设置为调用窗口即可。然后在任务栏中激活WPF应用程序不仅会激活MainWindow,还会激活模态子窗口并将其带到前面。

ChildWindow C = new ChildWindow();
C.Owner = this;
C.ShowDialog();

答案 2 :(得分:10)

将Topmost设置为True(Topmost = True)会使对话框位于系统中所有窗口的顶部(不仅仅是在应用程序中)。

因此,您可以尝试在主窗口中注册激活事件:

Activated += WindowActivated;
每当应用程序的另一个主窗口变为活动状态时,

并激活模式对话框的所有者窗口。

private void WindowActivated(object sender, EventArgs e)
{
    Window window = Application.Current.Windows.OfType<YourMainWindow>().FirstOrDefault(p => p != this && !p.IsActive && p.OwnedWindows.Count > 0);
    if (window != null)
    {
        window.Activate();
    }
}

这个简单的黑客假设你的所有子窗口都是模态的,但你可以编写一个更复杂的逻辑。

答案 3 :(得分:3)

我最终在这里结合使用了几个答案。接受的答案起初很有用,但正如此处的其他人指出设置Topmost = true意味着窗口始终高于任何其他正在运行的应用程序。我的解决方案是:

var myWindow = new MyWindowType();
myWindow.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);

我最初使用过:

myWindow.Owner = Application.Current.MainWindow;

但是,如果您打开三个窗口,此方法会导致问题:

MainWindow
   |
   -----> ChildWindow1

               |
               ----->  ChildWindow2

然后设置ChildWindow2.Owner = Application.Current.MainWindow会将窗口的所有者设置为祖父窗口,而不是父窗口。

为了加快速度,我已将其添加为Visual Studio中的代码段。如果您将以下内容添加到工具 - &gt;代码段管理器 - &gt;我的代码片段:

<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2010/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>MVVM Set owner of page to be current active window</Title>
      <Shortcut>owner</Shortcut>
    </Header>
    <Snippet>
      <Code Language="CSharp">
        <![CDATA[System.Windows.Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

键入“所有者”并双击标签键会自动为您添加“Application.CurrentWindows...”部分。

答案 4 :(得分:1)

不得不做一些修改。 我必须设置所有者并激活窗口。 检查弹出窗口并激活窗口,如下所示。

        var enumerator = Application.Current.Windows.GetEnumerator();
        while (enumerator.MoveNext())
        {
            Window window = (Window)enumerator.Current;
            if (window != null && window.GetType() == typeof(PopUpWindow))
            {
                window.Activate();
            }
        }