代码之家  ›  专栏  ›  技术社区  ›  Dirk Vollmar

如何在非模态对话上正确实现模态对话?

  •  6
  • Dirk Vollmar  · 技术社区  · 15 年前

    在WPF应用程序中,我希望实现以下行为,这些行为似乎并不简单:

    从主窗口( Window1 )用户打开非模态窗口( Window2 ,并且该非模态窗口可能会显示模态对话框。( Window3 )

    问题是,每当显示模式对话框时,当用户关闭对话框时,主窗口将在后台消失(假定有其他应用程序的窗口打开)。

    我用的方法有什么问题吗 Window.Owner Window.Show() / Window.ShowDialog() ,这是一个bug还是不受支持的东西?

    以下简单的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 窗1 :

    <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 窗口2 :

    <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 窗口3 :

    <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 回复  |  直到 12 年前
        1
  •  8
  •   Dirk Vollmar    15 年前

    微软 confirms this as a bug 在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();
            }
        }
    }
    

    (请注意,解决方法总是将主窗口置于前台,这可能与预期行为不同)