Forms.OpenFileDialog() and Forms.FolderBrowserDialog() initial path behavior - c#

In my application I use both OpenFileDialog and FolderBrowserDialog on button click handlers:
var fileDialog = new System.Windows.Forms.OpenFileDialog();
var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
Strange thing is that when calling OpenFileDialog it starts in explorer from folder in which file was chosen last time.
But FolderBrowserDialog opens MyComputer each time in explorer no matter what folder was chosen last time. How can I get same behavior (remembering last chosen folder) for `FolderBrowserDialog'?
It's also interesting where 'OpenFileDialog' stores folder of last chosen file? Does windows stores it for each application?

You can set FolderBrowserDialog's selected folder using the SelectedPath property before opening:
var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
folderDialog.RootFolder = System.Environment.SpecialFolder.MyComputer;
folderDialog.SelectedPath = <variable_where_you_stored_the_last_path>;
For example:
private string _lastFolderDialog = null;
// ...
var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
folderDialog.SelectedPath = _lastFolderDialog;
if(folderDialog.ShowDialog() == DialogResult.OK)
{
_lastFolderDialog = folderDialog.SelectedPath;
}
As for the OpenFileDialog, I think you mean:
fileDialog.InitialDirectory =
Environment.GetFolderPath(System.Environment.SpecialFolder.MyComputer);
However that won't work, since MyComputer doesn't have a path. Try this instead:
fileDialog.InitialDirectory = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
You can check for other CLSIDs in the registry under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID
As you have already discovered, if InitialDirectory is set to null, it'll remember the last opened folder. This won't happen with FolderBrowserDialog though
All that said, and as I stated in the comments, the FolderBrowserDialog is pretty much obsolete and you should not use it at all. According to the MSDN for the native API (SHBrowseForFolder) that supports it:
For Windows Vista or later, it is recommended that you use IFileDialog with the FOS_PICKFOLDERS option rather than the SHBrowseForFolder function. This uses the Open Files dialog in pick folders mode and is the preferred implementation.
You may want to check this question (which in turn links to this page) or this other question on how to implement IFileDialog with FOS_PICKFOLDERS in .NET

Related

How Read File Path From a .dat file then open the program When Pressing The Launch Button?

I have a problem Where I cant make my program automatically read the given file path inside the .dat and be ready to launch the program when pressing launch file without opening openFileDialog and choosing the program every time.
the code im using here is for the user to enter the file path for the first time then create a file path .dat file and it works with now issues.
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string path = Path.Combine(desktop, "LS\\Fail-SafePath.dat");
openFileDialog.InitialDirectory = filePath;
openFileDialog.Filter = " PlayGTAV (*.exe)|PlayGTAV.exe";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
var fileStream = openFileDialog.OpenFile();
using (StreamReader reader = new StreamReader(fileStream))
{
fileContent = reader.ReadToEnd();
}
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine(filePath);
}
After that that i have a start button for it
private void panel21_MouseClick(object sender, MouseEventArgs e)
{
Process.Start(filePath);
}
This works well when the user does it for the first time but now I want it to read that .dat file path automatically without having to ask the user for the file path every single time which I don't know how to do and need help with please.
I was thinking to do it like that: When Pressing the Launch button (After the first time) The Program Checks if the Fail-SafePath.dat Exists if Yes it reads the lines from it and starts the program from the given path without opening OpenFileDialog.
I'm Using Visual Studio, Windows Form.
If it's a file that the application will always need, then something like you mentioned:
I was thinking to do it like that: When Pressing the Launch button (After the first time) The Program Checks if the Fail-SafePath.dat Exists if Yes it reads the lines from it and starts the program from the given path without opening OpenFileDialog.
Could work easily enough. You could have your application look for it in the default location, and if not there, have your user select it.
Another solution could be using something like Application Settings or User Settings, which are values persisted between executions of .NET projects.
Depending on your full application design, you could also have the file path and other settings stored in some database or other data storage. There are a lot of ways to accomplish this.
EDIT: To elaborate further on the Application Settings
The application settings are very easy to read and write to.
You just need to create the ones you want, before trying to use them.
They can be created by:
Open Visual Studio.
In Solution Explorer, expand the Properties node of your project.
Double-click the .settings file in which you want to add a new setting. The default name for this file is Settings.settings.
In the Settings designer, set the Name, Value, Type, and Scope for your setting. Each row represents a single setting.
To read from your settings:
this.FilePath= Properties.Settings.Default.FilePath;
To write to and save the setting:
Properties.Settings.Default.FilePath= Path.GetFullPath("importantFilePath");
Properties.Settings.Default.Save();

How to Get the Target Folder

I was just at Open directory dialog, and they said "get this package, and do this and this to get a folder select window to show up". Well, that all works great, using the Windows API Code Pack-Shell package. However, now I want to get the actual folder that is selected. I didn't notice them mentioning this anywhere.
I tried to do string folderLocation = Convert.ToString(dialog); (dialog is the variable for opening the folder window), but that only gave me like the property of the variable. I also tried this: CommonFileDialogResult result = dialog.ShowDialog();
string folderLocation = Convert.ToString(result);
But that just gave me "Ok" - which I take it is the result of it, instead of the actual folder.
The result of ShowDialog just indicates wether the user clicked OK, cancel, or just closed the window.
CommonOpenFileDialog can be used for both files and folders, so it's a bit surprising when used as a folder picker, but the path is stored in FileName.
var dlg = new CommonOpenFileDialog();
dlg.IsFolderPicker = true;
if(dlg.ShowDialog() == CommonFileDialogResult.Ok) {
Console.WriteLine(dlg.FileName);
}
If I understood correctly, you want to get Folder for a selected file? If that's the case, you can take FileInfo for that file, and extract folfer from it. Like this:
System.IO.FileInfo fInfo = new System.IO.FileInfo(oFD1.FileName);
MessageBox.Show(fInfo.DirectoryName);
PS. oFD1 is OpenFileDialog

C# - Microsoft.Win32.SaveFileDialog Filename Issue

I have a problem where if you set the filename in the dialog box to a sub directory within the initial directory you set it to and then clicking 'Save', the dialog window doesn't actually save the file but opens the sub directory which I could still interact with.
For example If I set the initial directory for the dialog to 'C:\MainDir' and that directory consists of SubDir1, SubDir2, then in the save file dialog I could see that I am in the initial directory with two sub directories. If I set the filename to SubDir1 (no extension) in the dialog, and then I hit 'Save', what happens is instead of saving the file as 'filename.extension' the dialog opens the directory specified by the file name.
Here's what I currently have:
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = ext;
dlg.AddExtension = true;
dlg.FileName = filename;
dlg.Filter = filter;
dlg.FileOk += OnFileDialogOk;
dlg.InitialDirectory = dir;
bool? dlgRes = dlg.ShowDialog();
Is this something that can be easily fixed?
Quick Answer: No.
You cannot override the default save method of Windows OS.
What you can do is perhaps to verify whether the filename you wanted to use (in this instance, SubDir) exists already as a directory. If it does, then you would need to change that name, as that will only manifest the behavior you've already seen.
Side Note: Just imagine you have a very important folder which contains critical files, and Windows would let you save a file that is named with that directory. That is a disaster waiting to happen.
The only ways I can think of doing this are a bit extreme:
You could roll your own dialog
You could modify the functionality of the standard dialog
The answers found here: Customizing OpenFileDialog could help with that.
I guess I should also note that while it may seem helpful to accommodate this kind of input and automatically append the extension, it'll be counter-intuitive to many users who will expect the default behaviour.
In short, I'd probably think twice about this.

Where are paths previously used in the program stored (e.g. FileDialog paths)?

According to this msdn article one of the sources for InitialDirectory property used in FileDialog is:
A path that was previously used in the program, perhaps retained from the last directory or file operation.
...
So if you selected your first file from folder x, the next time you try to select a file it will open up the FileDialog with with folder x selected (saving you having to navigate there).
Playing around with notepad this seems to carry across opening a file, saving a file, opening a file and even when printing with "Microsoft XPS Document Writer" which brings up it's own dialog.
So my question is where is this value stored between dialogs? I would like to be able to see what it is and potentially change it? The specific area i would like to change it is in the "Microsoft XPS Document Writer" printer which brings up it's own dialog. So it's not as simple as just setting the initalDirectory Value.
It's stored in the registry, somewhere in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\ (LastVisitedPidlMRU).
You should take a look at this link:
MRU locations are what you are looking at!
Here's a way for accessing it:
var openFileDialog1 = new OpenFileDialog();
string path = openFileDialog1.InitialDirectory;
// you can change path if you want
openFileDialog1.InitialDirectory = path;
// after you are donw you can display you dialog
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// do something
}
Another way is to use Directory.SetCurrentDirectory method which sets the application's current working directory
And from Microsoft website, it is stored at this location in the registry:
//The MRU lists for Windows Explorer-style dialog boxes are stored by file type for each user in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU
hope this helps

Is it possible to make a FolderBrowserDialog's default path show up in a library instead of the actual disk?

I know that if I set SelectedPath before I show the dialog I can get it to have a folder open by default when the dialog opens. However, the folder I want to use is very far down the list alphabetically. I have that same folder as one of my Libraries in Windows and it shows up at the of the listing, is there any way to have it default to the library version of the folder instead of the hard drive version of the folder?
Another potential solution would be if it did still use the drive version but it automatically scrolled the window down to where it was selected. Is there any way to do either of these solutions?
How it currently shows up
How I would like it to show up
Set your root folder and selected path as such and it will auto-scroll there for you on the dialog opening:
FolderBrowserDialog dlg = new FolderBrowserDialog();
dlg.RootFolder = Environment.SpecialFolder.MyComputer;
dlg.SelectedPath = #"E:\Vetcentric";
dlg.ShowDialog();
The problem you run into is that if you watch the property assignments after selecting a folder located in the libraries hierarchy, it will still assign it to the genereic path that you would get via going through my computer.
Use a Reset() call. This will make it auto-scroll.
string prevpath = folderBrowserDialog1.SelectedPath;
folderBrowserDialog1.Reset();
folderBrowserDialog1.SelectedPath = bc.myWorkingDir;
folderBrowserDialog1.ShowNewFolderButton = true;
DialogResult dr = folderBrowserDialog1.ShowDialog();
if (dr == DialogResult.OK || dr == DialogResult.Yes)
{
bc.myWorkingDir = folderBrowserDialog1.SelectedPath;
}
folderBrowserDialog1.SelectedPath = prevpath;
Just set the path Libraries\VetCentric...
before you open should do it I think.
The easiest way would probably be to put shortcuts to the folders you want into your starting folder. Then, just double click on the shortcut and it will take you to your folder.
Otherwise you will need to use the Shell Library API
See: Using Libraries in your Program

Categories