C# 在WPF应用程序中保存用户设置的方法?

C# 在WPF应用程序中保存用户设置的方法?,c#,.net,wpf,settings,C#,.net,Wpf,Settings,您建议在WPF windows(桌面)应用程序中持久化用户设置的方法是什么?请注意,这个想法是用户可以在运行时更改其设置,然后关闭应用程序,然后在稍后启动应用程序时,应用程序将使用当前设置。这样,应用程序设置就好像没有改变一样 Q1-数据库还是其他方法?我确实有一个sqlite数据库,我无论如何都会使用它,因此在数据库中使用一个表会和任何方法一样好吗 问题2-如果数据库:什么样的数据库表设计?一个表,其中包含一个可能具有的不同数据类型的列(例如,string、long、DateTime等),或者

您建议在WPF windows(桌面)应用程序中持久化用户设置的方法是什么?请注意,这个想法是用户可以在运行时更改其设置,然后关闭应用程序,然后在稍后启动应用程序时,应用程序将使用当前设置。这样,应用程序设置就好像没有改变一样

Q1-数据库还是其他方法?我确实有一个sqlite数据库,我无论如何都会使用它,因此在数据库中使用一个表会和任何方法一样好吗

问题2-如果数据库:什么样的数据库表设计?一个表,其中包含一个可能具有的不同数据类型的列(例如,
string
long
DateTime
等),或者仅一个表,其中包含一个字符串作为值,您必须对其值进行序列化和反序列化?我认为第一个会更容易,如果没有太多的设置,开销也不会太大


Q3-应用程序设置可用于此目的吗?如果是的话,在这里启用持久性是否需要任何特殊任务?在这种情况下,在应用程序设置设计器中使用“默认”值会发生什么情况?默认设置是否会覆盖在运行应用程序之间保存的任何设置?(或者您是否需要不使用默认值)

除了数据库之外,您还可以使用以下选项来保存与用户相关的设置

  • HKEY\U当前用户下的注册表

  • AppData
    文件夹中的文件中

  • 在WPF中使用
    设置
    文件,并将其范围设置为用户

  • 您可以使用,考虑到读写设置所花费的时间,使用数据库不是最好的选择(特别是当您使用web服务时)

    这里有几个链接解释了如何实现这一点并在WPF中使用它们-


    解决这个问题最典型的方法是:隔离存储

    将控件状态序列化为XML或其他格式(如果使用WPF保存依赖项属性,尤其容易),然后将文件保存到用户的独立存储中

    如果你真的想使用应用程序设置,我自己也曾尝试过类似的方法……不过下面的方法很容易适应使用独立存储:

    class SettingsManager
    {
        public static void LoadSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
        {
            EnsureProperties(sender, savedElements);
            foreach (FrameworkElement element in savedElements.Keys)
            {
                try
                {
                    element.SetValue(savedElements[element], Properties.Settings.Default[sender.Name + "." + element.Name]);
                }
                catch (Exception ex) { }
            }
        }
    
        public static void SaveSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
        {
            EnsureProperties(sender, savedElements);
            foreach (FrameworkElement element in savedElements.Keys)
            {
                Properties.Settings.Default[sender.Name + "." + element.Name] = element.GetValue(savedElements[element]);
            }
            Properties.Settings.Default.Save();
        }
    
        public static void EnsureProperties(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
        {
            foreach (FrameworkElement element in savedElements.Keys)
            {
                bool hasProperty =
                    Properties.Settings.Default.Properties[sender.Name + "." + element.Name] != null;
    
                if (!hasProperty)
                {
                    SettingsAttributeDictionary attributes = new SettingsAttributeDictionary();
                    UserScopedSettingAttribute attribute = new UserScopedSettingAttribute();
                    attributes.Add(attribute.GetType(), attribute);
    
                    SettingsProperty property = new SettingsProperty(sender.Name + "." + element.Name,
                        savedElements[element].DefaultMetadata.DefaultValue.GetType(), Properties.Settings.Default.Providers["LocalFileSettingsProvider"], false, null, SettingsSerializeAs.String, attributes, true, true);
                    Properties.Settings.Default.Properties.Add(property);
                }
            }
            Properties.Settings.Default.Reload();
        }
    }
    
    类设置管理器
    {
    公共静态void加载设置(FrameworkElement发送器、字典savedElements)
    {
    确保属性(发送方、保存方);
    foreach(savedElements.Keys中的FrameworkElement元素)
    {
    尝试
    {
    SetValue(savedElements[element],Properties.Settings.Default[sender.Name+“+element.Name]);
    }
    捕获(例外情况除外){}
    }
    }
    公共静态void保存设置(FrameworkElement发送者、字典保存元素)
    {
    确保属性(发送方、保存方);
    foreach(savedElements.Keys中的FrameworkElement元素)
    {
    Properties.Settings.Default[sender.Name+”“+element.Name]=element.GetValue(savedElements[element]);
    }
    Properties.Settings.Default.Save();
    }
    公共静态属性(FrameworkElement发送方、字典保存项)
    {
    foreach(savedElements.Keys中的FrameworkElement元素)
    {
    布尔哈斯酒店=
    Properties.Settings.Default.Properties[sender.Name+“+element.Name]!=null;
    如果(!hasProperty)
    {
    SettingsAttributedDictionary属性=新的SettingsAttributedDictionary();
    UserScopedSettingAttribute属性=新的UserScopedSettingAttribute();
    Add(attribute.GetType(),attribute);
    SettingsProperty属性=新的SettingsProperty(sender.Name+“+”元素.Name,
    savedElements[element].DefaultMetadata.DefaultValue.GetType(),Properties.Settings.Default.Providers[“LocalFileSettingsProvider”],false,null,SettingsSerializeAs.String,attributes,true,true);
    Properties.Settings.Default.Properties.Add(属性);
    }
    }
    Properties.Settings.Default.Reload();
    }
    }
    
    ……和

      Dictionary<FrameworkElement, DependencyProperty> savedElements = new Dictionary<FrameworkElement, DependencyProperty>();
    
    public Window_Load(object sender, EventArgs e) {
               savedElements.Add(firstNameText, TextBox.TextProperty);
                    savedElements.Add(lastNameText, TextBox.TextProperty);
    
                SettingsManager.LoadSettings(this, savedElements);
    }
    
    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                SettingsManager.SaveSettings(this, savedElements);
            }
    
    Dictionary savelelements=new Dictionary();
    公共窗口加载(对象发送器、事件参数){
    savedElements.Add(firstNameText,TextBox.TextProperty);
    savedElements.Add(lastNameText,TextBox.TextProperty);
    SettingsManager.LoadSettings(这是savedElements);
    }
    私有无效窗口\u关闭(对象发送方,System.ComponentModel.CancelEventArgs e)
    {
    SettingsManager.SaveSettings(这是savedElements);
    }
    
    我通常通过定义一个自定义的[
    可序列化的
    ]设置类并将其序列化到磁盘来完成这类工作。在您的例子中,您可以将其作为字符串blob轻松地存储在SQLite数据库中

    根据我的经验,将所有设置存储在数据库表中是最好的解决方案。甚至不要担心性能。今天的数据库速度很快,可以轻松地在一个表中存储数千列。在我进行系列化/反系列化之前,我通过艰苦的方式学会了这一点。将其存储在本地文件或注册表中有一个大问题-如果您必须支持您的应用程序,而计算机处于关闭状态-用户不在其前面-您无能为力。。。。如果设置在DB中-您可以更改它们,viola更不用说您可以比较设置….

    您可以将设置信息存储为
    设置中XML的
    字符串。默认值
    。创建一些类来存储配置数据,并确保它们是
    [Serializable]
    。然后,使用以下帮助程序,您可以序列化这些对象的实例——或T的
    List
    (或数组
    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);
    }
    
    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;
            }
        }
    }
    
    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);
        }
    }
    
    Imports System.IO
    Imports System.Xml.Serialization
    
    Public Class XControl
    
    Private _person_ID As Integer
    Private _person_UID As Guid
    
    'load from file
    Public Function XCRead(filename As String) As XControl
        Using sr As StreamReader = New StreamReader(filename)
            Dim xmls As New XmlSerializer(GetType(XControl))
            Return CType(xmls.Deserialize(sr), XControl)
        End Using
    End Function
    
    'save to file
    Public Sub XCSave(filename As String)
        Using sw As StreamWriter = New StreamWriter(filename)
            Dim xmls As New XmlSerializer(GetType(XControl))
            xmls.Serialize(sw, Me)
        End Using
    End Sub
    
    'all the get/set is below here
    
    Public Property Person_ID() As Integer
        Get
            Return _person_ID
        End Get
        Set(value As Integer)
            _person_ID = value
        End Set
    End Property
    
    Public Property Person_UID As Guid
        Get
            Return _person_UID
        End Get
        Set(value As Guid)
            _person_UID = value
        End Set
    End Property
    
    End Class