简体   繁体   中英

Using a CommonOpenFileDialog to select a folder but still show files within the folder in Windows 10

I'm trying to use CommonOpenFileDialog to allow users to select a folder, but also view the files that within the folder in the dialog. Currently my code allows the user to only select a folder, but files within it are hidden, which causes users to think they have selected a wrong (empty) folder.

using (var dlg = new CommonOpenFileDialog()
{
    Title = "Select folder to import from",
    AllowNonFileSystemItems = true,
    IsFolderPicker = true,
    EnsurePathExists = true,
    Multiselect = false,
    ShowPlacesList = true
})
{
    if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
    {
        //Do things with the selected folder and the files within it...
    }
}

How can I achieve my goal for applications targeting Windows 10?

NOTE: There is a very similar question titled " How can I make CommonOpenFileDialog select folders only, but still show files? ". This question already has good answers, however, none of the solutions work in Windows 10 . Because the existing question is outdated (asked over 9 years ago) and doesn't apply for Windows 10, this question is specifically asking for a solution that works on a Windows 10 device.

I think that is not possible with the CommonOpenFileDialog
See: How to use IFileDialog with FOS_PICKFOLDER while still displaying file names in the dialog

The only way is to create your own custom dialog or you can use folder dialog with P/Invoke (based on SHBrowseForFolder like FolderBrowserDialog ).
See: http://www.pinvoke.net/default.aspx/shell32.shbrowseforfolder

Copy the class from the link above and add the option BIF_BROWSEINCLUDEFILES .

public string SelectFolder(string caption, string initialPath, IntPtr parentHandle)
{
    _initialPath = initialPath;
    ...
    bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;

Now files are displayed in the dialog unfortunately only like FolderBrowserDialog .

Is it possible to use something similar? Handle FolderChanging event and read the folder name?

private string SelectFolder()
{
    using (var dlg = new CommonOpenFileDialog()
    {
        Title = "Select folder to import from",
        AllowNonFileSystemItems = true,
        IsFolderPicker = true,
        EnsurePathExists = true,
        Multiselect = false,
        ShowPlacesList = true,
        InitialDirectory = "C:\\" //This must be handled manually
    })
    {
        dlg.FolderChanging += Dlg_FolderChanging;
        if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
        {
            //Do things with the selected folder and the files within it...
            string selectedFolder = dlg.InitialDirectory;
            string dlgFileName = dlg.FileName;
            if (Directory.Exists(dlgFileName))
                selectedFolder = dlgFileName;
            else if (File.Exists(dlgFileName))
                selectedFolder = Path.GetDirectoryName(dlgFileName);
            else if (string.IsNullOrWhiteSpace(lastKnownFolder))
                selectedFolder = lastKnownFolder;

            return selectedFolder;
        }
    }

    return null;
}

private string lastKnownFolder = "";

private void Dlg_FolderChanging(object sender, CommonFileDialogFolderChangeEventArgs e)
{
    lastKnownFolder = e.Folder;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM