我正在使用Window.ShowDialog()
在我的WPF(MVVM)应用程序中打开一个模态窗口,但它允许我使用Windows任务栏(Windows 7)导航到其他窗口。
考虑一下:
我在我的应用程序中打开了3个非模态窗口。现在其中一个使用Window.ShowDialog()
打开一个模态窗口。我还将Application.MainWindow
设置为模态窗口的所有者。这是因为我使用MVVM消息传递而消息处理程序打开一个新窗口集中在App.xaml.cs
。窗口打开模态 - 没有问题。但是,Windows 7允许我从任务栏切换到其他应用程序窗口。这导致了模态窗口落在另一个窗口后面的情况,我不喜欢这个窗口。
只要我打开模态,我就无法在其他窗口上执行任何操作,但如果模态窗口始终保持在顶部,只要打开它就会很好。有没有办法在模态打开时禁用任务栏切换?仅供参考 - 从应用程序启动的所有打开的窗口在任务栏上显示为单独的条目。
提前致谢!
答案 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();
}
}