Reputation: 2566
I'm trying to learn how to save date in xml-files and already can do it when I provide the path (eg. C:\Users\Name\Documents) in the code itself. But I want the user to choose the file path once when he opens the program the first time and then use this file path forever.
By now I'm that far:
string xmlFilePath = "C:\\Users\\Name\\Documents\\Visual Studio 2012\\Projects\\ToDoList\\xmlList.xml";
XmlTextWriter xWriteList = new XmlTextWriter(xmlFilePath, Encoding.UTF8);
Then I have a whole bunch of writing commands which all work well. Just to clarify my problem: When it says "C:\Users and so on in my sample code, I want the file path the user selected once. I know I can let the user select a file path with the FileDialog, but I don't know how to save this path somehow. Obviously I can't save it in a xml again because the user would have to choose that path again.
I hope you understand my question and thank everybody who answers in advance.
Upvotes: 2
Views: 5821
Reputation: 11955
What you need is a settings file, and it can be an XML file. A settings file that is private to your program. It will always be in the same place, so your program knows where it is. It also can be user specific.
I create a class library to include in all my company projects, it has a class file, the company name, so its obviously about the company's location in the Program Files directory, and in the Common directory to store settings and the User's directory to store settings.
So, I'll show those three, but the one you will want will either be the User's settings directory or the Common. The problem with using the Program's directory is that it may be in C:\Program Files
and the operating system won't let you write there unless your program is running as Admin.
The Common directory & files:
public const string Company = "YourCompanyName";
/// <summary>
/// Common to all users Company data directory.
/// </summary>
public static DirectoryInfo CommonDataDirectory
{
get
{
string env = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string path = Path.Combine(env, Company);
return new DirectoryInfo(path);
}
}
/// <summary>
/// Common to all users data file.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static FileInfo CommonDataFile(params string[] path)
{
string fullName = Paths.Combine(CommonDataDirectory.FullName, path);
return new FileInfo(fullName);
}
The user's settings directory:
/// <summary>
/// User's common data directory
/// </summary>
/// <returns></returns>
public static DirectoryInfo UserDataDirectory
{
get
{
string env = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = Path.Combine(env, Company);
return new DirectoryInfo(path);
}
}
/// <summary>
/// File in user's common data directory
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static FileInfo UserDataFile(params string[] path)
{
return new FileInfo(Paths.Combine(UserDataDirectory.FullName, path));
}
The program directory: (Where the program/executable is running from)
public static DirectoryInfo ProgramDirectory
{
get
{
string executablePath = System.Windows.Forms.Application.StartupPath;
return new DirectoryInfo(executablePath);
}
}
/// <summary>
/// Get's the file in the exectuable's directory, which would be
/// ProgramFiles/applicationName/filename
/// </summary>
public static FileInfo ProgramFile(params string[] path)
{
string file = Paths.Combine(ProgramDirectory.FullName, path);
return new FileInfo(file);
}
Here's the Paths class referenced in the above code.
One other thing, you will want to create a subdirectory from these for your specific program. So that your different programs can have files with the same name like Settings.xml
and not conflict with each-other.
I have an ApplicationBase class that uses the Company class for Application specific locations. Example:
/// <summary>
/// The application's name
/// </summary>
public static string ApplicationName
{
get { return System.Windows.Forms.Application.ProductName; }
}
/// <summary>
/// Common to all users, application's data directory.
/// </summary>
public static DirectoryInfo CommonDataDirectory
{
get
{
string fullName = Path.Combine(Company.CommonDataDirectory.FullName, ApplicationName);
return new DirectoryInfo(fullName);
}
}
/// <summary>
/// Common to all users, file in application's data directory.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static FileInfo CommonDataFile(params string[] name)
{
string fullName = Paths.Combine(CommonDataDirectory.FullName, name);
return new FileInfo(fullName);
}
I leave it to you to create the other two, the User's and Program's Directory property and File method.
Upvotes: 0
Reputation: 1700
Sounds like you need a ApplicationSettingsBase
derived setting.
//Application settings wrapper class
sealed class FormSettings : ApplicationSettingsBase
{
[UserScopedSettingAttribute()]
public string FilePath
{
get { return (string )(this["FilePath"]); }
set { this["FilePath"] = value; }
}
}
used like this:
<on form load handler>
frmSettings1 = new FormSettings();
if(frmSettings1.FilePath==null)
{
frmSettings1.FilePath = PromptForLocation();
}
<form exit handler>
frmSettings1.Save();
where PromptForLocation
well. Prompts for a location, using, like you " can let the user select a file path with the FileSaveDialog
"
It should be noted that this will provide a "per user" setting, that gets stored in the user profile directory. If another user logs on, they get their own copy of this setting.
Upvotes: 0
Reputation: 137148
You need to take the file from the SaveFileDialog.FileName
property and save it in a class variable.
That will persist it while the program is running.
To persist this between sessions you need to save it somewhere on the users hard drive. You can do this by using an application configuration or settings file.
Set up a string property in this and then save the chosen filename to that.
On loading:
globalFileName = Properties.Settings.Default.FileName;
On closing the application:
Properties.Settings.Default.FileName = globalFileName;
Properties.Settings.Default.Save();
Upvotes: 1