为什么不能在窗口构造函数中显示两次FolderBrowserDialog ?

本文关键字:两次 FolderBrowserDialog 显示 不能 窗口 构造函数 为什么 | 更新日期: 2023-09-27 18:02:23

出于好奇,我想知道为什么我不能在Window的构造函数中一个接一个地显示FolderBrowserDialog的两个不同实例,但可以在WindowLoaded事件中做到这一点。

    示例1只显示第一个对话框(fbd1),而不显示下一个。示例2显示了两个对话框。

例1:

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        using (var fbd1 = new FolderBrowserDialog()) {
            fbd1.ShowDialog();
        }
        using (var fbd2 = new FolderBrowserDialog()) {
            fbd2.ShowDialog();
        }
    }
}

例二:

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e) {
        using (var fbd1 = new FolderBrowserDialog()) {
            fbd1.ShowDialog();
        }
        using (var fbd2 = new FolderBrowserDialog()) {
            fbd2.ShowDialog();
        }
    }
}

顺便说一下,我也用WinForms测试过,结果几乎是一样的。

它不能在Form的构造函数FormLoad事件中工作,但在Shown事件中工作。

为什么不能在窗口构造函数中显示两次FolderBrowserDialog ?

你喜欢的答案实际上不是正确答案,它实际上确实激活了第二个对话框。激活状态和z轴顺序是不同的窗口属性。你只是看不到对话框,因为你失去了前景。只有当你有一个窗口可以留在前台时,你才能保留它。

程序在启动后有~6秒的时间用自己的窗口窃取前景。这个超时很容易看到,Windows显示游标。AppStarting光标(带有沙漏的小箭头)。这使得第一个对话框进入前景。然而,接下来发生的事情注定会出错。当用户关闭对话框时,你的应用就没有可以移动到前台的窗口了。Windows现在开始寻找另一个窗口放在前台,不可避免地是另一个进程拥有的窗口。很可能是VS主窗口,当你调试的例子。6秒已经过了。第二个对话框将显示并被激活,但它当然与那个窗口重叠。

一个冷酷的事实是,一个对话框必须总是有一个所有者。FolderBrowserDialog对此有点过于宽容了,它为您提供了一个没有所有者参数的ShowDialog()重载。很方便,但并不总是正确的。它在底层使用GetActiveWindow()来查找所有者。如果没有,那么桌面窗口就成了主人,麻烦就来了,

正如Reza Aghaei在他的第二条评论中所说:

当您关闭第一个对话框时,第二个对话框出现了,但是自从你的Form目前不可见,在任务栏中也不可见,它不激活第二个对话框,而它在other后面打开窗户只要按下Alt+Tab就会看到打开的窗口,你会看到第二个对话。但是,当您的表单是可见的(例如,当运行

你将不会有这个问题。

这就是我好奇的答案。