using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace FSI.Lib.WinSettings { /// /// The class makes it very easy to save your application /// settings to an XML file. /// /// /// /// To use the class, simply derive your own settings class from /// and add the public properties that you want to be /// saved as settings. You can then call the and /// methods to read or write those settings to an XML /// file. /// /// /// Your derived class' constructor should initialize your settings properties to /// their default values. /// /// /// Two attributes are available for public properties in your derived class. The /// first is . Use this attribute if you /// want the setting to be encrypted when saved to file. When using this attribute on /// any property, you must provide a valid encryption password to the /// constructor. /// /// /// The second is the . Use this attribute /// on any properties that are used internally by your code and should not saved to /// file. /// /// /// All public properties without the /// attribute must be of one of the supported data types. This includes all the basic /// data types as well as and . /// All other types will raise an exception. /// /// /// /// The following example creates a settings class called MySettings with /// several properties, two of which are encrypted when saved to file. /// /// public class MySettings : XmlSettings /// { /// // Define properties to be saved to file /// public string EmailHost { get; set; } /// public int EmailPort { get; set; } /// /// // The following properties will be encrypted /// [EncryptedSetting] /// public string UserName { get; set; } /// [EncryptedSetting] /// public string Password { get; set; } /// /// // The following property will not be saved to file /// // Non-public properties are also not saved to file /// [ExcludedSetting] /// public DateTime Created { get; set; } /// /// public MySettings(string filename) /// : base(filename, "Password123") /// { /// // Set initial, default property values /// EmailHost = string.Empty; /// EmailPort = 0; /// UserName = string.Empty; /// Password = string.Empty; /// /// Created = DateTime.Now; /// } /// } /// /// /// /// public abstract class XmlSettings : Settings { /// /// Gets or sets the name of the XML settings file. /// [ExcludedSetting] public string FileName { get; set; } /// /// Constructs an instance of the class. /// /// Name of the settings file. /// Encryption password. May be null if /// no settings use the /// attribute. public XmlSettings(string filename, string password = null) : base(password) { if (string.IsNullOrWhiteSpace(filename)) throw new ArgumentException("A valid file name is required.", nameof(filename)); FileName = filename; } /// /// Performs internal load operations. /// /// Settings to be loaded. public override void OnLoadSettings(IEnumerable settings) { if (File.Exists(FileName)) { // Load XML document XmlDocument doc = new XmlDocument(); doc.Load(FileName); // Read settings foreach (Setting setting in settings) { XmlNode node = doc.DocumentElement?.SelectSingleNode(setting.Name); if (node != null) setting.SetValueFromString(node.InnerText); } } } /// /// Performs internal save operations. /// /// Settings to be saved. public override void OnSaveSettings(IEnumerable settings) { // Create settings document XmlDocument doc = new XmlDocument(); doc.AppendChild(doc.CreateXmlDeclaration("1.0", "UTF-8", null)); doc.AppendChild(doc.CreateElement("Settings")); // Write settings foreach (Setting setting in settings) { string value = setting.GetValueAsString(); if (value != null) { XmlElement element = doc.CreateElement(setting.Name); element.InnerText = value; #if NET472 doc.DocumentElement.AppendChild(element); #elif NET6_0 doc.DocumentElement!.AppendChild(element); #endif } } doc.Save(FileName); } } }