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?
Vous devez définir la propriété RestoreDirectory
sur true
ainsi que la propriété InitialDirectory
.
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;
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);
}
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, "*.*");
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.
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";
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:
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:
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.
savefiledialog.InitialDirectory = Application.StartupPath;
savefiledialog.RestoreDirectory = true;
testé il y a une seconde.
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
"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)
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();
}
}
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é.