c# - approach for saving user settings in a WPF application?
You can use Application Settings for this, using database is not the best option considering the time consumed to read and write the settings(specially if you use web services).
Here are few links which explains how to achieve this and use them in WPF -
User Settings in WPF
Quick WPF Tip: How to bind to WPF application resources and settings?
A Configurable Window for WPF
Update: Nowadays I would use JSON.
I also prefer to go with serialization to file. XML files fits mostly all requirements. You can use the ApplicationSettings
build in but those have some restrictions and a defined but (for me) very strange behavior where they stored. I used them a lot and they work. But if you want to have full control how and where they stored I use another approach.
- Make a class Somewhere with all your settings. I named it
MySettings
- Implement Save and Read for persistence
- Use them in you application-code
Advantages:
- Very Simple approach.
- One Class for Settings. Load. Save.
- All your Settings are type safe.
- You can simplify or extend the logic to your needs (Versioning, many Profiles per User, etc.)
- It works very well in any case (Database, WinForms, WPF, Service, etc...)
- You can define where to store the XML files.
- You can find them and manipulate them either by code or manual
- It works for any deployment method I can imagine.
Disadvantages: - You have to think about where to store your settings files. (But you can just use your installation folder)
Here is a simple example (not tested)-
public class MySettings
{
public string Setting1 { get; set; }
public List<string> Setting2 { get; set; }
public void Save(string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
xmls.Serialize(sw, this);
}
}
public MySettings Read(string filename)
{
using (StreamReader sw = new StreamReader(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
return xmls.Deserialize(sw) as MySettings;
}
}
}
And here is how to use it. It's possible to load default values or override them with the user's settings by just checking if user settings exist:
public class MyApplicationLogic
{
public const string UserSettingsFilename = "settings.xml";
public string _DefaultSettingspath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\" + UserSettingsFilename;
public string _UserSettingsPath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\UserSettings\\" +
UserSettingsFilename;
public MyApplicationLogic()
{
// if default settings exist
if (File.Exists(_UserSettingsPath))
this.Settings = Settings.Read(_UserSettingsPath);
else
this.Settings = Settings.Read(_DefaultSettingspath);
}
public MySettings Settings { get; private set; }
public void SaveUserSettings()
{
Settings.Save(_UserSettingsPath);
}
}
maybe someone get's inspired by this approach. This is how I do it now for many years and I'm quite happy with that.
You can store your settings info as Strings
of XML in the Settings.Default
. Create some classes to store your configuration data and make sure they are [Serializable]
. Then, with the following helpers, you can serialize instances of these objects--or List<T>
(or arrays T[]
, etc.) of them--to String
. Store each of these various strings in its own respective Settings.Default
slot in your WPF application's Settings
.
To recover the objects the next time the app starts, read the Settings
string of interest and Deserialize
to the expected type T
(which this time must be explcitly specified as a type argument to Deserialize<T>
).
public static String Serialize<T>(T t)
{
using (StringWriter sw = new StringWriter())
using (XmlWriter xw = XmlWriter.Create(sw))
{
new XmlSerializer(typeof(T)).Serialize(xw, t);
return sw.GetStringBuilder().ToString();
}
}
public static T Deserialize<T>(String s_xml)
{
using (XmlReader xw = XmlReader.Create(new StringReader(s_xml)))
return (T)new XmlSerializer(typeof(T)).Deserialize(xw);
}