2

Okay, so please don't flame me too much, this is my 1st question here, and maybe what I am trying to do is not even possible. Obviously I am not an expert; that's why I am coming to you. :)

I have searched all over here, MSDN, and the rest of the internet (most of which points back here) without any luck. I did see one question asking about using the OpenFileDialog to select a folder instead of a file. I am almost certain that I have seen this in mainstream applications, but the question was marked as being too vague, and that particular caveat was unaddressed in the responses.

I have some text boxes that need file/folder paths. I want to simplify the two methods that handle this, into one. The only difference, is that once selects a file, and the other selects a folder. For simplicity and readability, I'd like to consolidate them.

Is this possible, without literally putting the contents of each code method into a big IF ?

Here are the two methods:

private void FolderBrowser(object sender, EventArgs e)
    {
        TextBox SenderBox = sender as TextBox;
        if (SenderBox.Text != "")//if the text box is not empty
        {
            //set the selected path to the text box's current contents (incase of accidental entry)
            FileBrowserDialog.FileName = SenderBox.Text;
        }
        if (FileBrowserDialog.ShowDialog() == DialogResult.OK)
        {
            SenderBox.Text = FileBrowserDialog.FileName;
        }
    }

private void FileBrowser(object sender, EventArgs e)
    {   //basically the same as the folder browser above, but for selecting specific files
        TextBox SenderBox = sender as TextBox;
        if (SenderBox.Text != "")//if the text box is not empty
        {
            //set the selected path to the text box's current contents (incase of accidental entry)
            FileBrowserDialog.FileName = SenderBox.Text;
        }
        if (FileBrowserDialog.ShowDialog() == DialogResult.OK)
        {
            SenderBox.Text = FileBrowserDialog.FileName;
        }
    }

I have added a Tag to each TextBox, indicating if it needs a file or a folder. I'd like to use the Tag as the condition by which I determine if I should be using a file or folder browser. This is where my ignorance shows; I had envisioned something like this NONWORKING code:

private void browser(object sender, EventArgs e)
    {
        //cast sender as a textbox
        TextBox tBox = (TextBox)sender;
        object browser = null;

        if (tBox.Tag.ToString().Equals("Folder"))
        {
            browser = new FolderBrowserDialog();
        }
        else
        {
            browser = new OpenFileDialog();                
        }

        if (tBox.Text != "")//if the text box is not empty
        {
            //set the selected path to the text box's current contents (incase of accidental entry)
            browser.FileName = tBox.Text;
        }
        if (browser.ShowDialog() == DialogResult.OK)
        {
            tBox.Text = browser.FileName;
        }
    }

Am I crazy, or is there a way to accomplish what I have in mind? To be clear, I want to know if there is:

  1. An existing Object/Method that would allow for the selection of a file or a folder, or
  2. A way to dynamically re-define an object as a different type of object
  3. Any other way to use 1 Method to dynamically allow for the use of OpenFileDialog or FileBrowserDialog based on some Tag defined on the calling object.
Pezius
  • 117
  • 3
  • 12
  • 1
    possible duplicate of [How do you configure an OpenFileDialog to select folders?](http://stackoverflow.com/questions/31059/how-do-you-configure-an-openfiledialog-to-select-folders) – rducom Feb 24 '15 at 21:06
  • thanks @Sharped Clarification: I want to know if this is possible using native methods, without any 3rd party code, but based on your link, it looks like it may not be. – Pezius Feb 24 '15 at 21:12
  • Check [this question](http://stackoverflow.com/questions/428410/select-either-a-file-or-folder-from-the-same-dialog-in-net). The answers talk about a chance to do this via P/Invoke. – Josh Part Feb 24 '15 at 21:23

4 Answers4

1

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.

Dasanko
  • 579
  • 8
  • 16
0

Try using FolderBrowserDialogEx.

See detailed answers here: How do you configure an OpenFileDialog to select folders?

Community
  • 1
  • 1
Colin
  • 4,025
  • 21
  • 40
0

Both dialogs (FileOpenDialog and FolderBrowserDialog) inherit from CommonDialog; however, this base class has no property to retrieve the result. Moreover, the property is named differently in both dialogs.

You can solve the problem by creating a wrapper. Inheritance is the proper way of re-defining an object as different type.

public abstract class FileFolderDialogBase
{
    public abstract bool ShowDialog();
    public string Result { get; protected set; }
}

public class FileDialog : FileFolderDialogBase
{
    public override bool ShowDialog()
    {
        var ofd = new OpenFileDialog();
        if ofd.ShowDialog() == DialogResult.OK) {
            Result = ofd.FileName;
            return true;
        }
        return false;
    }
}

public class FolderDialog : FileFolderDialogBase
{
    public override bool ShowDialog()
    {
        var fbd = new FolderBrowserDialog();
        if (fbd.ShowDialog() == DialogResult.OK)
            Result = fbd.SelectedPath;
            return true;
        }
        return false;
    }
}

Usage:

var dialog = textBox.Tag == "Folder" ? new FolderDialog() : new FileDialog;
if (dialog.ShowDialog()) {
    textBox.Text = dialog.Result;
}

You can push it further by creating a factory class

public static class FileFolderDialog
{
    public static FileFolderDialogBase Create(string type)
    {
        swich (type.ToLowerInvariant()) {
            case "folder":
            case "dir":
            case "directory":
                return new FolderDialog();
            default:
                return new FileDialog();
        }
    } 
}

Usage

var dialog = FileFolderDialog.Create(textBox.Tag);
if (dialog.ShowDialog()) {
    textBox.Text = dialog.Result;
}
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

why you not try extending the TextBox Class? It's easy and reusable and you only need to drag and drop your custom control to the WinForm

    class FileTextBox : System.Windows.Form.TextBox{
       //===>This enumeration is more readable insted of a string XD
       public enum DialogType{
         File,Folder
       }
     //===>This property we will handle what kind of Dialog to show
    public DialogType OpenDialogType{
      get;
      set;
    }

    //===>This is where Object Oriented Programming a& Design do his magic
    public System.Windows.Forms.DialogResult ShowDialog(string Title =""){
      //===>This function is where we define what kind of dialog  to show
      System.Windows.Forms.DialogResult Result =   System.Windows.Forms.DialogResult.None ;
      object Browser=null;

           switch(this.OpenDialogType){
                  case DialogType.File:
                  Browser = new OpenFileDialog();
                  ((Browser)OpenFileDialog).Title= Title;
                   if(this.Text.Trim() !="" && this.Text != null ){
                     ((Browser)OpenFileDialog).FileName = this.Tex;
                   }
                  Result = ((Browser)OpenFileDialog).ShowDialog();

                  break;

                  case DialogType.Folder:
                  Browser = new FolderBrowserDialog ();
                  ((Browser)FolderBrowserDialog).Description = Title;

                  if(this.Text.Trim() !="" && this.Text != null ){
                      ((Browser)FolderBrowserDialog).RootFolder = this.Text; 
                  } 

                  Result = ((Browser)FolderBrowserDialog).ShowDialog();
                  break;
           }
    return Result;//===>We return thi dialog result just if we want to do something else
    }

}
/*
Create a class and copy/paste this code, I think is going to work because
I didn't compiled then go to ToolBox window find this control and Drag & Drop
to your WinForm and in the property window find OpenDialogType property
and this is where you kind define the behavior of OpenDialog();

I'm currently working in a little project in Vs where I create a custom
UI Control downloaded from my git repository 

https://github.com/MrAlex6204/GYMSystem

*/
MrAlex6204
  • 167
  • 7