1

Out of curiosity, I wonder why I can't show two different instances of FolderBrowserDialog one after the other in the constructor of a Window, but can do it in the Window's Loaded event.

  • The Example 1 just shows the first dialog (fbd1), and doesn't show the next one.
  • The Example 2 shows the two dialogs.

Example 1 :

public partial class MainWindow : Window {

    public MainWindow() {
        InitializeComponent();

        using (var fbd1 = new FolderBrowserDialog()) {
            fbd1.ShowDialog();
        }
        using (var fbd2 = new FolderBrowserDialog()) {
            fbd2.ShowDialog();
        }
    }
}

Example 2 :

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

By the way, I've also tested with WinForms, and this is almost the same.

It doesn't work in the Form's constructor and in the Form's Load event, but works in the Shown event.

Drarig29
  • 1,902
  • 1
  • 19
  • 42
  • 4
    There is no problem with showing 2 `FolderBrowserDialog` in constructor of `Form`. The only thing that you should pay attention is, when `ShowDialog` is called, the code following it is not executed until after the dialog box is closed. So the second one appears after you closed the first one. – Reza Aghaei Aug 15 '16 at 14:11
  • 1
    When you close the first dialog, the second one appears, but since your `Form` is not visible at the moment and is not visible in task-bar, it doesn't activate the second dialog, while it's open behind other windows. Just press Alt+Tab to see open windows and you will see the second dialog too. But when your `Form` is visible (for example when run code in `Shown`) you will not have this issue. – Reza Aghaei Aug 15 '16 at 14:20
  • The code you have posted works fine, I feel like there may be some other code in between the 2 dialogs that is interfering? – DavidG Aug 15 '16 at 14:21
  • @RezaAghaei No. And this is exactly why I asked this question. The behavior you've described only exists in the Load event, and NOT in the constructor. – Drarig29 Aug 15 '16 at 14:21
  • Nope, it works fine in the loaded event too. What code did you use to assign the `Window_Loaded` method to the event? – DavidG Aug 15 '16 at 14:23
  • The Load event and Constructor behavior is the same. Read [my second comment](http://stackoverflow.com/questions/38956642/why-cant-show-folderbrowserdialog-twice-in-window-constructor#comment65267786_38956642) carefully. – Reza Aghaei Aug 15 '16 at 14:23
  • 1
    @RezaAghaei You're right with the 2nd comment. Indeed the Dialog is just not activated ;) I see it in Alt+Tab. Thank you. – Drarig29 Aug 15 '16 at 14:24

2 Answers2

6

The answer you like is not in fact the correct answer, it actually does activate the second dialog. Activation state and Z-order are distinct windows properties. You just can't see the dialog because you lost the foreground. One you can only ever keep when you have a window that can stay in the foreground.

A program gets ~6 seconds to steal the foreground with its own window after it starts up. That timeout is easy to see, Windows displays the Cursors.AppStarting cursor (small arrow with hourglass). That worked to get the 1st dialog into the foreground. What happens next is however doomed to go wrong. When the user closes the dialog then your app has no window left that can be moved into the foreground. Windows now goes hunting for another window to put in the foreground, inevitably one that's owned by another process. Pretty likely to be the VS main window when you debug for example. And the 6 seconds has expired. The 2nd dialog will show up and get activated but of course it is overlapped by that window.

Cold hard fact is that a dialog must always have an owner. FolderBrowserDialog is a bit too forgiving about that, providing you with a ShowDialog() overload without an owner argument. Very convenient, not always correct. It uses GetActiveWindow() under the hood to find an owner. If there isn't one then the desktop window becomes the owner, trouble ahead, otherwise without throwing an exception.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

As Reza Aghaei said in his 2nd comment :

When you close the first dialog, the second one appears, but since your Form is not visible at the moment and is not visible in task-bar, it doesn't activate the second dialog, while it's open behind other windows. Just press Alt+Tab to see open windows and you will see the second dialog too. But when your Form is visible (for example when run code in Shown) you will not have this issue.

This is the answer to my curiosity.

Drarig29
  • 1,902
  • 1
  • 19
  • 42