Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly implement a modal dialog on top a non-modal dialog?

In a WPF application I would like to implement the following behaviour which doesn't seem to work straightforward:

From the main window (Window1) the user opens a non-modal window (Window2), and that non-modal window may display a modal dialog (Window3).

The problem is that whenever the modal dialog has been shown, the main window disappears in the background (given that there are windows of other applications open) when the user closes the dialogs.

Is there anything wrong in the way that I use Window.Owner and Window.Show()/Window.ShowDialog(), is it a bug or is it something simply not supported?

The following simple WPF application demonstrates this behavior:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Window2 win = new Window2();
        win.Owner = this;
        win.Show();
    }
}

public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Window3 win = new Window3();
        win.Owner = this;
        win.ShowDialog();
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}

public partial class Window3 : Window
{
    public Window3()
    {
        InitializeComponent();
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}

XAML Window1:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1">

    <Button Click="Button_Click">Show non-modal window</Button>
</Window>

XAML Window2:

<Window x:Class="WpfApplication1.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window2">
    <StackPanel>
        <Button Click="Button_Click">Show modal dialog</Button>
        <Button Name="btnClose" Click="btnClose_Click">Close</Button>
    </StackPanel>
</Window>

XAML Window3:

<Window x:Class="WpfApplication1.Window3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window3">

    <Button Name="btnClose" Click="btnClose_Click">Close</Button>
</Window>

UPDATE: Fixed copy&paste error in the code. This is .NET 3.5 SP1 in case it matters.

like image 495
Dirk Vollmar Avatar asked Jan 04 '10 17:01

Dirk Vollmar


People also ask

What is non-modal dialog?

In contrast, nonmodal (or modeless) dialogs and windows do not disable the main content: showing the dialog box doesn't change the functionality of the user interface. The user can continue interacting with the main content (and perhaps even move the window, minimize it, etc.) while the dialog is open.

What is modal and non-modal window?

The main difference lies in the way you can interact with each screen. While a Non-Modal Screen allows users to simply go back to the parent screen, the Modal Screen requires users to complete an action before returning to the main window (“save” in our example) or cancel the current action.

What is the difference between a modal and a dialog?

2 Answers. Show activity on this post. A modal window is a windows that runs on top of an application, so that you can't do anything at all with the applciation until you have closed the modal window. A jQuery dialog is not a separate window, so technically it can't be a modal window.

What is non-modal?

A non-modal function moves from one task to another without switching between official or apparent modes of operation.


1 Answers

Microsoft confirms this as a bug in WPF:

This isn't a regression from previous releases so it doesn't make the bar to be fixed for this version of the product. We'll look into this for a future release.

In the meantime, this can be worked around by activating the owner window when the child window is closing.

Sample code:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void NonModalButtonClick(object sender, RoutedEventArgs e)
    {
        new Window1 { Owner = this }.Show();
    }

    private void ModalButtonClick(object sender, RoutedEventArgs e)
    {
        new Window1 { Owner = this }.ShowDialog();
    }

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        if (this.Owner != null)
        {
            this.Owner.Activate();
        }
    }
}

(Note that the workaround will always bring the main window into foreground which might be different than the expected behavior)

like image 178
Dirk Vollmar Avatar answered Oct 20 '22 21:10

Dirk Vollmar