Как правильно реализовать модальное диалоговое окно поверх немодального? - PullRequest
6 голосов
/ 04 января 2010

В приложении WPF я хотел бы реализовать следующее поведение, которое, кажется, не работает просто:

В главном окне (Window1) пользователь открывает немодальное окно (Window2), и в немодальном окне может отображаться модальное диалоговое окно (Window3).

Проблема заключается в том, что всякий раз, когда отображается модальное диалоговое окно, основное окно исчезает в фоновом режиме (при условии, что открыты окна других приложений), когда пользователь закрывает диалоги.

Что-то не так в том, как я использую Window.Owner и Window.Show() / Window.ShowDialog(), это ошибка или что-то просто не поддерживается?

Следующее простое приложение WPF демонстрирует это поведение:

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>

ОБНОВЛЕНИЕ: Исправлена ​​ошибка копирования и вставки в коде. Это .NET 3.5 SP1, если это имеет значение.

1 Ответ

8 голосов
/ 14 января 2010

Microsoft подтверждает это как ошибку в WPF:

Это не регрессия из предыдущих выпусков, поэтому он не делает планку фиксированной для этой версии продукта. Мы рассмотрим это в будущем выпуске.

Тем временем это можно обойти, активировав окно владельца, когда дочернее окно закрывается.

Пример кода:

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

(Обратите внимание, что обходной путь всегда выводит главное окно на передний план, которое может отличаться от ожидаемого поведения)

...