Modal Dialog not showing on top of other windows

孤街醉人 提交于 2019-12-28 06:18:28

问题


I am using Window.ShowDialog() to open a modal window in my WPF (MVVM) application, but it lets me navigate to other windows using the Windows taskbar (Windows 7).

Consider this: I have 3 non-modal windows open in my application. Now One of these opens a modal window using Window.ShowDialog(). I also set Application.MainWindow as the owner of the modal window. This is so because I am using MVVM messaging and the message handler to open a new window is centralized in App.xaml.cs. The window does opens modally - no issues there. However, Windows 7 allows me to swtich to the other application windows from the taskbar. This leads to a situation where the modal window goes behind another window, which I prefer not to have.

I can't do anything on other windows as long as I have the modal open, but it would be nice if the modal window always remained on top as long as it's open. Is there a way I can disable taskbar switching when the modal is open? FYI - all open windows launched from the app appear as separate entries on the taskbar.

Thanks in advance!


回答1:


There isn't any code to base this off of, but it sounds like you have left off some properties on the Window you've created and expected ShowDialog to apply additional "dialog" semantics:

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();



回答2:


Just set the owner property of the Window to the calling window. Then the activation of the WPF application in taskbar not just activates the MainWindow but also the modal child window and brings it to the front.

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



回答3:


Setting Topmost to True (Topmost=True) causes the dialog to be on the top of all windows in the system (not only in application).

So you can try to register the event Activated in your main window:

Activated += WindowActivated;

and activate an owner window of the modal dialog every time when another main window of your application become active.

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();
    }
}

This simple hack assumes all your children windows are modal, but you can write a more sophisticated logic.




回答4:


I ended up using a combination of a couple of the answers here. The accepted answer was useful at first but as other people on here have pointed out setting Topmost = true means that the window is always above any other applications running. My solution was this:

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

I initially used:

myWindow.Owner = Application.Current.MainWindow;

However, this method causes problems if you have three windows open like this:

MainWindow
   |
   -----> ChildWindow1

               |
               ----->  ChildWindow2

Then setting ChildWindow2.Owner = Application.Current.MainWindow will set the owner of the window to be its grandparent window, not parent window.

To speed things up, I've added it as a code snippet in Visual Studio. If you add the following to Tools --> Code Snippet Manager --> My Code Snippets:

<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>

Typing 'owner' and double-tapping the tab key will add the 'Application.CurrentWindows...' part in for you automatically.




回答5:


Had to do a bit of modification. I had to set the owner and activate the window. Check for the pop up window and activate the window as given below.

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


来源:https://stackoverflow.com/questions/6417558/modal-dialog-not-showing-on-top-of-other-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!