2010-04-09 4 views
2

Peut-être que certains d'entre vous ont rencontrés auparavant ....Comment obtenir les noms de fichiers en utilisant OpenFileDialog dans .NET (fichier de 1000+ MultiSelect)

Je suis l'ouverture de fichiers pour l'analyse syntaxique. J'utilise OpenFileDialog, bien sûr, mais je suis limité à un tampon de 2048 sur la chaîne .FileNames. Ainsi, je ne peux sélectionner que quelques centaines de fichiers. C'est OK pour la plupart des cas. Cependant, par exemple, j'ai dans un cas 1400 fichiers à ouvrir. Savez-vous un moyen de le faire avec la boîte de dialogue ouverte. Je veux juste le tableau de chaînes de .FileNames, je passe cela à la classe parser.

Je pensais aussi à offrir une option FolderBrowserDialog, puis j'utiliserais une autre méthode pour simplement faire une boucle sur tous les fichiers d'un répertoire, comme la classe DirectoryInfo. Je ferais cela en dernier recours si je ne peux pas avoir une solution tout en un.

+7

Vous voulez l'utilisateur de sélectionner 1400 fichiers * manuellement * ??? –

+1

La propriété 'FileNames' est de type' string [] ', c'est-à-dire qu'il s'agit d'un tableau de chaînes. Alors, de quel tampon parlez-vous? Pourriez-vous clarifier s'il vous plaît? Notez qu'un chemin individuel (c'est-à-dire une entrée dans le tableau) est limité en longueur, ce qui est une restriction de système d'exploitation/système de fichiers. –

+1

@Adam Robinson: Vous avez déjà appuyé sur Ctrl + A sur votre clavier? –

Répondre

1

Ce que je fini par faire était d'écrire une méthode utilise le OpenFileDialog, mais vérifie la longueur de la chaîne de chemin indirectement. C'est si la méthode échoue, une erreur est affichée à l'utilisateur en leur disant qu'il y a trop de fichiers, puis un FolderBrowser est montré avec le dossier sélectionné que l'utilisateur regardait. J'ai également ajouté des options séparées pour importer des fichiers ou importer dossiers dans la barre de menus.

Voici le code pour le faire. Ce sont des méthodes dans une classe statique appelée DataFileIO où je mets tous les trucs customize IO pour l'écriture ou l'accès ou Excel xml, etc.

 public static string[] GetFiles() 
    { 
     string[] fileNames; 
     OpenFileDialog openFileDialog1 = new OpenFileDialog(); 

     openFileDialog1.InitialDirectory = UniversalDataImporter.Properties.Settings.Default.openFilePath; 
     openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"; 
     openFileDialog1.FilterIndex = 2; 
     openFileDialog1.RestoreDirectory = false; 
     openFileDialog1.Multiselect = true; 
     openFileDialog1.CheckFileExists = false; 

     try 
     { 
      DialogResult result = openFileDialog1.ShowDialog(); 
      if (result == DialogResult.OK && openFileDialog1.FileNames.Count() <501) 
      { 
       UniversalDataImporter.Properties.Settings.Default.openFilePath = 
        Path.GetDirectoryName(openFileDialog1.FileName); 
       UniversalDataImporter.Properties.Settings.Default.Save(); 
       return fileNames = openFileDialog1.FileNames; 
      } 
      else if (result == DialogResult.Cancel) 
      { 
       return null; 
      } 
      else 
      { 
       if (MessageBox.Show("Too many files were Selected. Would you like to import a folder instead?", 
        "Too many files...", MessageBoxButtons.YesNo) == DialogResult.Yes) 
       { 
        return fileNames = GetFilesInFolder(); 
       } 
       else 
       { 
        return null; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); 
      return null; 
     } 
    } 

    public static string[] GetFilesInFolder() 
    { 

     FileInfo[] fileInfo; 

     string pathName; 
     FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog(); 

     folderBrowserDialog.RootFolder = System.Environment.SpecialFolder.Desktop; 

     DialogResult results = folderBrowserDialog.ShowDialog(); 

     if (results == DialogResult.OK) 
     { 
      try 
      { 
       pathName = folderBrowserDialog.SelectedPath; 

       DirectoryInfo dir = new DirectoryInfo(pathName); 
       if (dir.Exists) 
       { 

        fileInfo = dir.GetFiles(); 

        string[] fileNames = new string[fileInfo.Length]; 

        for (int i = 0; i < fileInfo.Length; i++)//this is shit 
        { 
         fileNames[i] = fileInfo[i].FullName; 
        } 

        return fileNames; 
       } 
       else 
       { 
        return null; 
       } 


      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); 
       return null; 
      } 

     } 
     else if (results == DialogResult.Cancel) 
     { 
      return null; 
     } 
     else { return null; } 
    } 
1

mon gosh Je ne peux pas imaginer la sélection de 1400 fichiers dans une boîte de dialogue d'ouverture de fichier. Peut-être devriez-vous simplement autoriser l'utilisateur à entrer un filtre, puis effectuer un appel à System.IO.Directory.GetFiles.

+1

Choisissez un répertoire, tirez tous les noms de fichiers, laissez l'utilisateur filtrer ou ajoutez/supprimez manuellement plusieurs fichiers ou répertoires. C'est une meilleure solution que de taxer l'OFD et offre plus de flexibilité à l'utilisateur. – Will

1

Je choisirais certainement la route FolderBrowser. Je ne voudrais JAMAIS avoir à sélectionner 50-100 beaucoup moins de 1000+ fichiers manuellement. Mieux vaut récupérer le dossier, demander à ce que certains motifs correspondent et les sélectionner de cette façon. Du point de vue de l'utilisabilité, choisir un grand nombre de fichiers est un mauvais choix à mon humble avis.

1

Avez-vous des erreurs ou des exceptions? Êtes-vous certain d'utiliser le OpenFileDialog à partir de l'espace de noms System.Windows.Forms?

Le code suivant fonctionne parfaitement avec plus de 2000 fichiers sélectionnés:

System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog(); 
ofd.InitialDirectory = @"C:\Windows\system32\"; 
ofd.Multiselect = true; 
ofd.ShowDialog(); 

foreach (var file in ofd.FileNames) 
{ 
    Trace.WriteLine(file); 
} 
Questions connexes