Select either a file or folder from the same dialog in .NET
Technically, it is possible. The shell dialog used by FolderBrowseDialog has the ability to return both files and folders. Unfortunately, that capability isn't exposed in .NET. Not even reflection can poke the required option flag.
To make it work, you'd have to P/Invoke SHBrowseForFolder() with the BIF_BROWSEINCLUDEFILES flag turned on in BROWSEINFO.ulFlags (value = 0x4000). The P/Invoke is gritty, it is best to copy and paste the code from another source or the FolderBrowseDialog class itself with Reflector's help.
c# select Folders or Files in the same method
This is the easiest way I've found of solving this problem without relying on third party code, but you'll need to add some sanity checks, in case the user goofs around with the input:
OpenFileDialog ofd = new OpenFileDialog();
ofd.CheckFileExists = false;
string defaultFilename = "Select this folder";
ofd.FileName = defaultFilename;
if (ofd.ShowDialog().Value)
{
// Check if the user picked a file or a directory, for example:
if (!ofd.FileName.Contains(defaultFilename))
{
// File code
}
else // You should probably turn this into an else if instead
{
// Directory code
}
// Alternatively, but still as unsafe
if (File.Exists(ofd.FileName))
{
// File code
}
else
{
// Directory code
}
}
Basically, the "trick" here is to set OpenFileDialog's CheckFileExists to false.
Is there a dialog to select a mixture of multiple files and folders at once?
Below is a screenshot of the UI and some snippets of code (mostly event handlers) tied to the implementation of a file AND folder selection dialog I mentioned in my comment.
While all of the code related to navigating directories and actually retrieving filepaths is in a different layer of code (a wrapper around a version control API), this should give you an idea of how one might implement a file AND folder selection dialog with multiple item select enabled from a controls perspective. A simple button to zip the current selection could call GetSourceSelectedFilePaths
(or whatever you might choose to call it) and then zip all those paths together.
I suspect the System.IO.Directory
class contains almost all of the methods you would need to handle the file / directory navigation side of this.
This certainly isn't much aesthetically and I'm aware you are not keen on implementing this yourself, but it certainly is possible (and relatively easy if you can live with something that looks like this). If I had more time I would have replaced all those API wrapper calls with System.IO.Directory
method calls to make this a bit more clear.
// Method to display contents at current level (folders and files) to controls
private void AddToDisplayChildFolderContents(APIObject curVaultWrapper, ListBox childFolder_LB, ListBox childFiles_LB)
{
var curDocNames = curVaultWrapper.GetCurFolderDocNames(); // API wrapper call to get all documents in current folder
if (curDocNames.Count > 0)
{
childFiles_LB.Items.Clear();
childFiles_LB.Items.AddRange(curDocNames.ToArray());
}
var childFolderList = = curVaultWrapper.GetCurChildFolderNames(); // API wrapper call to get all folders in current folder
if (childFolderList.Count > 0)
{
childFolder_LB.Items.Clear();
childFolder_LB.Items.AddRange(returnStatus.items.ToArray());
}
}
// Method to navigate up one directory
private void srcGoUp_B_Click(object sender, EventArgs e)
{
if (VaultCopyConfig.SrcVault.DrillOutOfVaultFolder()) // API wrapper method returns true if current folder is root, points version controlled file system API wrapper one directory up
{
this.srcGoUp_B.Enabled = false;
}
DisplayVaultFolderContents(VaultCopyConfig.SrcVault, srcCurrentFolder_TB, srcDrill_IntoSubFolder_CB,
srcChildFolders_LB, srcFiles_LB);
}
// Method to navigate one directory lower
private void srcDrill_IntoSubFolder_CB_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedSubFolderName = srcDrill_IntoSubFolder_CB.Text;
VaultCopyConfig.SrcVault.DrillIntoVaultFolder(selectedSubFolderName, false); // call to our API wrapper
DisplayVaultFolderContents(vaultCopyConfig.srcVault, srcCurrentFolder_TB, srcDrill_IntoSubFolder_CB,
srcChildFolders_LB, srcFiles_LB);
this.srcGoUp_B.Enabled = true;
}
// Method that is called to aggregate all user selections (then sends to our API wrapper to actually validate / process / consolidate paths
private List<string> GetSourceSelectedFilePaths(bool dlgFlag)
{
var filePaths = new List<string>();
var validFolderNames = new List<string>();
var validFileNames = new List<string>();
if (srcChildFolders_LB.Items.Count > 0)
{
string selectedItem;
foreach (int i = 0; i < srcChildFolders_LB.Items.Count; i++)
{
if (srcChildFolders_LB.GetSelected(i))
{
selectedItem = srcChildFolders_LB.Items[i].ToString();
validFolderNames.Add(selectedItem);
}
}
}
if (srcFiles_LB.Items.Count > 0)
{
var selectedItem;
for (int i = 0; i < srcFiles_LB.Items.Count; i++)
{
if (srcFiles_LB.GetSelected(i))
{
selectedItem = srcFiles_LB.Items[i].ToString();
validFileNames.Add(selectedItem);
}
}
}
filePaths = VaultCopyConfig.SrcVault.GetSelectedFilePaths(validFolderNames, validFileNames, dlgFlag); // call to API wrapper to validate / consolidate list of all filepaths in user selection
return filePaths;
}
How do I use OpenFileDialog to select a folder?
As a note for future users who would like to avoid using FolderBrowserDialog
, Microsoft once released an API called the WindowsAPICodePack that had a helpful dialog called CommonOpenFileDialog
, that could be set into a IsFolderPicker
mode. The API is available from Microsoft as a NuGet package.
This is all I needed to install and use the CommonOpenFileDialog
. (NuGet handled the dependencies)
Install-Package Microsoft.WindowsAPICodePack-Shell
For the include line:
using Microsoft.WindowsAPICodePack.Dialogs;
Usage:
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
MessageBox.Show("You selected: " + dialog.FileName);
}
Related Topics
Different Forms of the Wcf Service Contract Interface
How to Get the Subscribers of an Event
What's Difference Between Environment.Exit() and Application.Shutdown()
When Using .Net MVC Radiobuttonfor(), How to Group So Only One Selection Can Be Made
Using Linq Except Not Working as I Thought
How to Figure Out Which Key of Modelstate Has Error
Unity3D Ui, Calculation for Position Dragging an Item
Adding Custom Properties for Each Request in Application Insights Metrics
Get Window State of Another Process
How to Serialize and Save a Gameobject in Unity
With Rx, How to Ignore All-Except-The-Latest Value When My Subscribe Method Is Running
Does Filestreamresult Close Stream
Executenonquery Doesn't Return Results
ASP.NET Core 2.0 Disable Automatic Challenge
ASP.NET MVC Routing - Add .HTML Extension to Routes
Why Does the Linq Cast<> Helper Not Work with the Implicit Cast Operator