【问题标题】:c# select Folders or Files in the same methodc# 以相同的方法选择文件夹或文件
【发布时间】:2015-04-26 16:35:20
【问题描述】:

好的,所以请不要太激怒我,这是我在这里的第一个问题,也许我想要做的甚至是不可能的。显然我不是专家;这就是我来找你的原因。 :)

我已经搜索了整个这里、MSDN 和互联网的其余部分(大部分都指向这里),但没有任何运气。我确实看到了一个问题,询问有关使用OpenFileDialog 选择文件夹而不是文件的问题。我几乎可以肯定我已经在主流应用程序中看到了这一点,但是这个问题被标记为过于模糊,并且在回复中没有解决这个特别的警告。

我有一些需要文件/文件夹路径的文本框。我想将处理此问题的两种方法简化为一种。唯一不同的是,一次选择文件,另一次选择文件夹。为了简单和可读性,我想合并它们。

这是否可能,而不是将每个代码方法的内容逐字放入一个大的IF 中?

这里有两种方法:

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

我为每个TextBox 添加了一个Tag,表示它需要文件还是文件夹。我想使用Tag 作为我确定是否应该使用文件或文件夹浏览器的条件。这就是我无知的地方;我曾设想过类似这样的非工作代码:

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

我疯了,还是有办法实现我的想法?说清楚,我想知道是否有:

  1. 允许选择文件或文件夹的现有对象/方法,或
  2. 一种将对象动态重新定义为不同类型对象的方法
  3. 任何其他方式使用 1 方法来动态允许使用基于调用对象上定义的一些 TagOpenFileDialogFileBrowserDialog

【问题讨论】:

标签: c# .net openfiledialog folderbrowserdialog


【解决方案1】:

这是我发现在不依赖第三方代码的情况下解决此问题的最简单方法,但您需要添加一些完整性检查,以防用户输入错误:

        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
            }
        }

基本上,这里的“技巧”是将 OpenFileDialog 的 CheckFileExists 设置为 false。

【讨论】:

  • 谢谢@Dasanko 这既简单又实用。非常感谢!
【解决方案2】:

尝试使用 FolderBrowserDialogEx。

在此处查看详细答案: How do you configure an OpenFileDialog to select folders?

【讨论】:

  • 感谢@Colin,但我正在寻找一种本地方法。
【解决方案3】:

两个对话框(FileOpenDialogFolderBrowserDialog)都继承自 CommonDialog;但是,此基类没有检索结果的属性。此外,两个对话框中的属性名称不同。

您可以通过创建包装器来解决问题。继承是将对象重新定义为不同类型的正确方法。

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

用法:

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

您可以通过创建工厂类来进一步推动它

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

用法

var dialog = FileFolderDialog.Create(textBox.Tag);
if (dialog.ShowDialog()) {
    textBox.Text = dialog.Result;
}

【讨论】:

    【解决方案4】:

    为什么不尝试扩展 TextBox 类? 它简单且可重复使用,您只需将自定义控件拖放到 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

    */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 2020-12-15
      • 2013-12-26
      相关资源
      最近更新 更多