web-dev-qa-db-fra.com

Définition du répertoire initial d'un SaveFileDialog?

Je voudrais un SaveFileDialog avec le comportement suivant:

  • La première fois que vous l'ouvrez, il passe à "Mes documents".

  • Ensuite, il va dans le dernier dossier sélectionné. Quelle est la meilleure façon d'y parvenir?

Si je ne mets pas InitialDirectory, il va dans le répertoire de l'exe - ce qui n'est pas ce que je veux. Il rappelle cependant le dernier répertoire sélectionné - même entre les exécutions.

Si je définis InitialDirectory, il ne se souvient pas du dernier répertoire sélectionné. Bien sûr, je pourrais enregistrer le dernier répertoire sélectionné dans le registre :( mais je cherche une meilleure solution.

      SaveFileDialog dialog = new SaveFileDialog();
      //??? dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
      dialog.ShowDialog();

Aucun conseil?

36
tom greene

Vous devez définir la propriété RestoreDirectory sur true ainsi que la propriété InitialDirectory .

33
Andrew Hare

Je ne sais pas pourquoi cela fonctionne, mais j'ai finalement réussi à le faire fonctionner pour moi.

J'ai trouvé que si je donnais le chemin complet, cela ne fonctionnerait pas, mais si je mettais ce chemin complet à l'intérieur de Path.GetFullPath (), alors cela fonctionnerait. L'examen des valeurs avant et après montre qu'elles sont identiques, mais cela ne fonctionnerait pas systématiquement sans elle et fonctionnerait avec.

//does not work
OpenFileDialog dlgOpen = new OpenFileDialog();
string initPath = Path.GetTempPath() + @"\FQUL";
dlgOpen.InitialDirectory = initPath;
dlgOpen.RestoreDirectory = true;

//works
OpenFileDialog dlgOpen = new OpenFileDialog();
string initPath = Path.GetTempPath() + @"\FQUL";
dlgOpen.InitialDirectory = Path.GetFullPath(initPath);
dlgOpen.RestoreDirectory = true;
15
Jeffrey Harmon

Assurez-vous de vérifier que le chemin du répertoire existe avant de définir la propriété de répertoire initial. Créez le répertoire s'il n'existe pas. c'est à dire

if (!Directory.Exists(FooDirectory))
{
     Directory.CreateDirectory(FooDirectory);
}
4
user1956901

Moi aussi, j'ai essayé différentes "solutions" trouvées à différents endroits, mais aucune d'entre elles ne semble fonctionner dès qu'il y a une entrée de liste MRU dans le registre:/Mais voici ma propre solution de contournement simple ...

Au lieu de définir la propriété InitialDirectory de la boîte de dialogue, définissez la propriété FileName sur votre chemin, mais combinée avec la Filter sélectionnée, par exemple:

dialog.FileName = Path.Combine(myPath, "*.*");
3
mousio

Les solutions de contournement suggérées n'ont pas fonctionné pour moi, donc après avoir trouvé Comment WPF OpenFileDialog suit-il le répertoire du dernier fichier ouvert? J'ai implémenté:

public static void SetInitialDirectory(this FileDialog dlg, string fileExtension, string initialDirectory)
        {
            // RestoreDirectory doesn't seem to be implemented - https://stackoverflow.com/questions/11144770/how-does-wpf-openfiledialog-track-directory-of-last-opened-file
            // so manually only set InitialDirectory if nothing is stored
            try
            {
                var mru = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\" + fileExtension;
                var rk = Registry.CurrentUser.OpenSubKey(mru);
                if (rk == null)
                {
                    dlg.InitialDirectory = initialDirectory;
                }
            }
            catch (Exception)
            {
                // SecurityException, ObjectDisposedException => allow default behaviour
            }
        }

Cela utilisera le répertoire initial fourni si la boîte de dialogue n'a pas été utilisée auparavant pour cette extension de fichier. Une fois la boîte de dialogue utilisée, elle revient au comportement par défaut consistant à se souvenir du répertoire précédent.

1
danio

J'ai trouvé que la définition de InitialDirectory sur null fonctionne d'abord autour de l'historique de l'utilisateur.

    OpenFileDialog dlgOpen = new OpenFileDialog();
    dlgOpen.InitialDirectory = null;
    dlgOpen.InitialDirectory = @"c:\user\MyPath";
1
user104933

Aucune des solutions proposées n'a malheureusement fonctionné pour moi.

En plus des spécifications OP, je voulais que le programme se souvienne du dernier emplacement de sauvegarde entre les exécutions. Pour cela, dans l'Explorateur de solutions Visual Studios sous ProjectName -> Properties -> Settings.settings, J'ai configuré la propriété suivante:

Settings.settings property: Name=PreviousPath, Type=string, Scope=User, leave Value empty

Parce que je garde le SaveFileDialog tout au long de l'exécution du programme, j'instancie au début. Puis dans le Command pour faire apparaître la boîte de dialogue:

if (string.IsNullOrEmpty(Settings.Default.PreviousPath))
{
    this.saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
}
else
{
    this.saveDialog.InitialDirectory = Settings.Default.PreviousPath;
}

this.saveDialog.FileName = "Default_File_Name";

bool result = this.saveDialog.ShowDialog() ?? false;

if (result)
{
    Settings.Default.PreviousPath = Path.GetDirectoryName(this.saveDialog.FileName);
    Settings.Default.Save();

    // Code writing to the new file...
}

Cela donne le comportement:

  • La première fois que le programme est exécuté et que la boîte de dialogue est ouverte, il accède à "Mes documents".
  • Exécutions consécutives et dialogue ouvert:
    • S'il est enregistré lors d'une précédente ouverture, il revient à l'emplacement de sauvegarde précédent.
    • S'il n'est pas enregistré lors d'une précédente ouverture, accédez à "Mes documents".
1
OhBeWise

Je voulais juste peser sur cette discussion (quelques années trop tard) car j'avais aussi un problème exact. Même si l'on est amené à croire que ce comportement - c'est-à-dire en utilisant un chemin par défaut la première fois puis le chemin sélectionné par la suite - peut être obtenu en utilisant les propriétés et fonctions d'openFileDialog, on ne peut tout simplement pas (pour l'instant)!

On pourrait changer le répertoire de travail par le chemin par défaut souhaité (par exemple Environment.CurrentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);) mais certains framework, comme Unity, n'aiment pas beaucoup cela et se terminent.

Pour cette raison, je me suis retrouvé avec ce code:

private bool firstDialogOpened = true;

public void BrowseFiles()
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "Model files (*.obj)|*.obj|All files (*.*)|*.*";
    openFileDialog.FilterIndex = 1;

    if (firstDialogOpened)
    {
        openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        firstDialogOpened = false;
    }

    if (openFileDialog.ShowDialog() == DialogResult.OK)
        filepath.text = openFileDialog.FileName;
}

Cela donne le comportement souhaité pour moi, même si j'aurais aimé une solution plus élégante.

0
savefiledialog.InitialDirectory = Application.StartupPath;
savefiledialog.RestoreDirectory = true;

testé il y a une seconde.

0
PauLEffect

Si vous utilisez la barre oblique n'importe où sur votre chemin, InitialDirectory ne fonctionne pas. Assurez-vous qu'ils sont convertis en barres obliques inverses

0
Ali Akbar

"En termes d'enregistrement d'un fichier de sortie dans un répertoire souhaité dans vb.net", voici comment j'ai trouvé que cela fonctionnait comme un charme:

Dim filcsv As String = fileNamey.Replace(".txt", "_Denied2.csv")
Dim filcsv2 As String = fileNamey.Replace(".txt", "_Approved2.csv")

Dim outputDirectory As String = "C:\Users\jlcmil\Documents\EnableMN\output\"
Dim totalPath As String = System.IO.Path.Combine(outputDirectory, filcsv)
Dim totalPath2 As String = System.IO.Path.Combine(outputDirectory, filcsv2)

Dim outDenied As StreamWriter = New StreamWriter(totalPath)
Dim outApproved As StreamWriter = New StreamWriter(totalPath2)
0
Andrew Mills

C'est ce que je me suis retrouvé, qui va avec où l'OP voulait pointer leur dialogue:

Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.InitialDirectory = null;

// May or may not want "saves", but this shows how to append subdirectories
string path = (Path.Combine(Environment.ExpandEnvironmentVariables("%USERPROFILE%"), "My Documents") + "\\saves\\");  

if (!Directory.Exists(path))
    Directory.CreateDirectory(path);

dlg.InitialDirectory = path;
dlg.RestoreDirectory = true;

if (dlg.ShowDialog().Value == true)
{
    // This is so you can have JUST the directory they selected
    path = dlg.FileName.Remove(dlg.FileName.LastIndexOf('\\'), dlg.FileName.Length - dlg.FileName.LastIndexOf('\\'));

    string filePath = Path.Combine(path, fileName);

    // This is "just-in-case" - say they created a new directory in the dialog,
    // but the dialog doesn't seem to think it exists because it didn't see it on-launch?
    if (!Directory.Exists(path))
        Directory.CreateDirectory(path);

    // Remove a file if it has the same name
    if (File.Exist(filePath))
        File.Delete(filePath);

    // Write the file, assuming you have and pass in the bytes
    using (FileStream fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write)
    {
        fs.Write(bytes, 0, (int)bytes.Length);
        fs.Close();
    }
}
0
vapcguy

J'ai fait quelques tests avec .NET 2.0 et il semble que si je définit FileName sur autre chose qu'une chaîne littérale, cela ne fonctionne pas. Lorsque j'utilise une méthode ou un accesstor pour définir la propriété, le répertoire initial est ignoré.

0
Icono123