Equivalent to UserSettings / ApplicationSettings in WPF dotnet core

前端 未结 6 1316
没有蜡笔的小新
没有蜡笔的小新 2020-12-23 16:32

What is the prefered way for persisting user settings for WPF applications with .Net Core >=3.0?

Created WPF .Net Core 3.0 Project (VS2019 V16.3.1) Now I have seen t

6条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-23 16:57

    Based on Funk's answer here's an abstract generic singleton-style variation that removes some of the administration around SettingsManager and makes creating additional settings classes and using them as simple as possible:

    Typed Settings class:

    //Use System.Text.Json attributes to control serialization and defaults
    public class MySettings : SettingsManager
    {
        public bool SomeBoolean { get; set; }
        public string MyText { get; set; }
    }
    

    Usage:

    //Loading and reading values
    MySettings.Load();
    var theText = MySettings.Instance.MyText;
    var theBool = MySettings.Instance.SomeBoolean;
    
    //Updating values
    MySettings.Instance.MyText = "SomeNewText"
    MySettings.Save();
    

    As you can see the number of lines to create and use your settings are just as minimal, and a bit more rigid as there are no parameters.

    The base class defines where settings are stored and allows only for one settings file per MySettings subclass - assembly and class names determine its location. For the purpose of replacing a properties file that is enough.

    using System;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    
    public abstract class SettingsManager where T : SettingsManager, new()
    {
        private static readonly string filePath = GetLocalFilePath($"{typeof(T).Name}.json");
    
        public static T Instance { get; private set; }
    
        private static string GetLocalFilePath(string fileName)
        {
            string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 
            var companyName = Assembly.GetEntryAssembly().GetCustomAttributes().FirstOrDefault();
            return Path.Combine(appData, companyName?.Company ?? Assembly.GetEntryAssembly().GetName().Name, fileName);
        }
    
        public static void Load()
        {
            if (File.Exists(filePath))
                Instance = System.Text.Json.JsonSerializer.Deserialize(File.ReadAllText(filePath));
            else
                Instance = new T(); 
        }
    
        public static void Save()
        {
            string json = System.Text.Json.JsonSerializer.Serialize(Instance);
            Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            File.WriteAllText(filePath, json);
        }
    }
    

    Some improvements might be made in disabling the constructor of the settings subclass and creation of SettingsManager.Instance without Load()ing it; that depends on your own use cases.

提交回复
热议问题