using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CarManagerV3.Forms { public partial class SettingsForm : Form { // Settings map (Maps settings to controls and default values + optional change event handler function that takes previous and new value) private readonly Dictionary settingsMap = new(); public SettingsForm() { InitializeComponent(); initializeSettingsMap(); } private void initializeSettingsMap() { // Initialize the settings map with setting keys, associated controls, default values, and optional change event handlers settingsMap["DataLocation"] = new SettingBinding( control: tbxDataLocation, defaultValue: Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\CarManagerV3", read: () => Properties.Settings.Default.DataLocation, // strongly typed write: v => Properties.Settings.Default.DataLocation = v, // strongly typed onChange: (before, after) => { // TODO: handle path change if needed }); settingsMap["AllowPrerelease"] = new SettingBinding( control: cbxPreRelease, defaultValue: false, read: () => Properties.Settings.Default.AllowPrerelease, write: v => Properties.Settings.Default.AllowPrerelease = v); } private void SettingsForm_Load(object sender, EventArgs e) { loadSettings(); } private void loadSettings() { foreach (var kvp in settingsMap) kvp.Value.Load(); } private void saveSettings() { foreach (var kvp in settingsMap) kvp.Value.Save(); Properties.Settings.Default.Save(); } private void resetSettings() { DialogResult confirmReset = MessageBox.Show( "Are you sure you want to reset all settings to their default values? This action cannot be undone.", "Confirm Reset", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (confirmReset != DialogResult.Yes) return; foreach (var kvp in settingsMap) kvp.Value.Reset(); Properties.Settings.Default.Save(); loadSettings(); } private void btnAccept_Click(object sender, EventArgs e) { saveSettings(); this.Close(); } private void btnDiscard_Click(object sender, EventArgs e) { this.Close(); } private void btnReset_Click(object sender, EventArgs e) { resetSettings(); } } internal interface ISettingBinding { void Load(); void Save(); void Reset(); } internal sealed class SettingBinding : ISettingBinding { private readonly Control control; private readonly T defaultValue; private readonly Func read; private readonly Action write; private readonly Action? onChange; public SettingBinding(Control control, T defaultValue, Func read, Action write, Action? onChange = null) { this.control = control; this.defaultValue = defaultValue; this.read = read; this.write = write; this.onChange = onChange; } public void Load() { T value = read(); ApplyToControl(value); } public void Save() { T before = read(); T after = ReadFromControl(); write(after); if (onChange != null && !EqualityComparer.Default.Equals(before, after)) onChange(before, after); } public void Reset() => write(defaultValue); private void ApplyToControl(T value) { switch (control) { case TextBox tb: tb.Text = value?.ToString() ?? string.Empty; break; case CheckBox cb: cb.Checked = value is bool b ? b : Convert.ToBoolean(value); break; default: throw new NotSupportedException($"Control type '{control.GetType().Name}' not supported for {typeof(T).Name}."); } } private T ReadFromControl() { object result = control switch { TextBox tb when typeof(T) == typeof(string) => tb.Text, CheckBox cb when typeof(T) == typeof(bool) => cb.Checked, _ => throw new NotSupportedException($"Cannot read {typeof(T).Name} from control type '{control.GetType().Name}'.") }; return (T)result; } } }