MilleB
MilleB

Reputation: 1580

CommonOpenFileDialog put my window behind all other windows

I'm using CommonOpenFileDialog (from Windows API Code Pack) to pick a directory and somehow it send my window to the back. This is really frustrating as I have to find it in the task bar and click on it again.

Here is the code:

    public string ShowPickDirectoryDialog()
    {
        var dialog = new CommonOpenFileDialog { IsFolderPicker = true };
        if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
        {
            return dialog.FileName;
        }
        return null;
    }

I found a similiar question here:

How to bring the main form back to the front after the file open dialog is closed

But I'm using WPF/MVVM and don't have access to the window object so none of those answer would work. So how do I make sure that my window are at the front after I used CommonOpenFileDialog when I don't have access to the window object? I also can't use the "TopMost" setting as that would put the window in front of the directory picker.

Or is there anything better than CommonOpenFileDialog that I should use (that isn't ugly)?

Upvotes: 3

Views: 3667

Answers (3)

SeA75
SeA75

Reputation: 11

using WPF and MVVM you can try this solution (with MVVMLight nuget installed):

VIEWMODEL

    public RelayCommand<YourWindow> ChooseFolderStringCommand { get; set;}

In the ctor for example:

      ChooseFolderStringCommand = new RelayCommand<YourWindow>( o => ChooseFolder(o));

    private void ChooseFolder(YourWindow win)
    {
            using (var dialog = new CommonOpenFileDialog {IsFolderPicker = true})
            {
                
                CommonFileDialogResult result = dialog.ShowDialog();

                if (result == CommonFileDialogResult.Ok)
                    ...
            }


            win?.Activate();
        }

In the button where trigger ChooseFolder command:

in XAML


<Button Command="{Binding ChooseFolderStringCommand}" CommandParameter="{Binding ElementName=YourWindow}">

Hope that this help.

Upvotes: 1

Roberto
Roberto

Reputation: 303

This work well but I prefer to use:

var window = Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.IsActive);
var dialogResult = browserDialog.ShowDialog(window);

and don't use window.Focus()

This make that the window doesn't go to back.

Upvotes: 5

Stealth Rabbi
Stealth Rabbi

Reputation: 10346

You can get the currently active window prior to opening the open file dialog, and then refocus that after the dialog is closed.

Ideally this method would be in a service. What's nice about this is that nothing else needs to have a reference to the particular owning View -- it can be obtained in this method.

    public string PromptForDirectorySelection(string summary, string initialPath)
    {
        var browserDialog = new CommonOpenFileDialog
        {
            Title = summary,
            IsFolderPicker = true,
            InitialDirectory = initialPath,
            AddToMostRecentlyUsedList = true,
            AllowNonFileSystemItems = false,
            EnsureFileExists = false,
            EnsurePathExists = true,
            EnsureReadOnly = false,
            EnsureValidNames = true,
            Multiselect = false,
            ShowPlacesList = true
        };

        // get the current active window, prior to showing and closing this dialog, so it can be re-focused later.
        var window = Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.IsActive);

        var dialogResult = browserDialog.ShowDialog();
        if (null != window)
        {
            window.Focus();
        }
        if (dialogResult == CommonFileDialogResult.Ok)
        {
            return browserDialog.FileName;
        }

        return null;
    }

Upvotes: 0

Related Questions