存储 UI 设置的最佳实践?

Posted

技术标签:

【中文标题】存储 UI 设置的最佳实践?【英文标题】:Best practices for storing UI settings? 【发布时间】:2010-09-19 19:08:58 【问题描述】:

我们目前正在计划一个更大的 WPF LoB 应用程序,我想知道其他人认为存储大量 UI 设置的最佳做法是什么,例如

扩展国家 菜单订单 尺寸属性 等等……

我不喜欢使用提供的 SettingsProvider(即 App.config 文件)存储数十个值的想法,尽管它可以用于使用自定义 SettingsProvider 将其存储在嵌入式数据库中。 能够使用某种数据绑定也是一个问题。 有没有人有同样的问题?

您如何存储大量 ui 用户设置?

【问题讨论】:

【参考方案1】:

我们将首选项文件存储在这里:

Environment.SpecialFolder.ApplicationData

将其存储为 xml“首选项”文件,这样在损坏时访问和更改并不难。

到目前为止,这对我们来说比注册表效果要好得多,如果有任何东西损坏或需要重置,它会更干净、更容易清除。

【讨论】:

【参考方案2】:

存储 UI 设置的更快方法是使用 Properties.Settings.Default 系统。它的好处是使用 WPF 绑定到值。 Example here。设置会自动更新和加载。

<Window ...
    xmlns:p="clr-namespace:UserSettings.Properties"
    Height="Binding Source=x:Static p:Settings.Default, Path=Height, Mode=TwoWay" 
    Width="Binding Source=x:Static p:Settings.Default, Path=Width, Mode=TwoWay" 
    Left="Binding Source=x:Static p:Settings.Default, Path=Left, Mode=TwoWay" 
    Top="Binding Source=x:Static p:Settings.Default, Path=Top, Mode=TwoWay">

...
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
 
    Settings.Default.Save(); 
    base.OnClosing(e); 

问题在于,如果您的应用程序很大,它很快就会变得一团糟。

另一种解决方案(此处有人提出)是使用 ApplicationData 路径将您自己的首选项存储到 XML 中。在那里,您可以构建自己的设置类并使用 XML 序列化程序来持久化它。这种方法使您能够从版本迁移到版本。虽然功能更强大,但此方法需要更多代码。

【讨论】:

【参考方案3】:

深入研究 aogan 的答案并将其与 decasteljau 的答案和他引用的博客文章相结合,这是一个示例,填补了我不清楚的一些空白。

xaml 文件:

<Window ...
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:MyApp"
    Height="Binding Source=x:Static p:MyAppSettings.Default, Path=MainWndHeight, Mode=TwoWay"
    Width="Binding Source=x:Static p:MyAppSettings.Default, Path=MainWndWidth, Mode=TwoWay"
    Left="Binding Source=x:Static p:MyAppSettings.Default, Path=MainWndLeft, Mode=TwoWay"
    Top="Binding Source=x:Static p:MyAppSettings.Default, Path=MainWndTop, Mode=TwoWay"
    ...

还有源文件:

namespace MyApp

    class MainWindow ....
    
        ...

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        
            MyAppSettings.Default.Save();
            base.OnClosing(e);
        
    

    public sealed class MyAppSettings : System.Configuration.ApplicationSettingsBase
    
        private static MyAppSettings defaultInstance = ((MyAppSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new MyAppSettings())));
        public static MyAppSettings Default
        
            get  return defaultInstance; 
        

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("540")]
        public int MainWndHeight
        
            get  return (int)this["MainWndHeight"]; 
            set  this["MainWndHeight"] = value; 
        

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("790")]
        public int MainWndWidth
        
            get  return (int)this["MainWndWidth"]; 
            set  this["MainWndWidth"] = value; 
        

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("300")]
        public int MainWndTop
        
            get  return (int)this["MainWndTop"]; 
            set  this["MainWndTop"] = value; 
        

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("300")]
        public int MainWndLeft
        
            get  return (int)this["MainWndLeft"]; 
            set  this["MainWndLeft"] = value; 
        
    

【讨论】:

【参考方案4】:

我们将所有内容存储在Isolation Storage 中(我们使用 ClickOnce 运行)。我们有一些要序列化的对象 (XmlSerializer)。

【讨论】:

【参考方案5】:

似乎由于某种原因正在失去人气;但注册表一直是此类设置的合适位置。

【讨论】:

注册表绝对不再是正确的地方。注册表损坏,不当使用可能导致安全问题,并可能违反 LUA/UAC 原则。 secureapps.blogspot.com/2006/10/… 好吧,UI 设置几乎与安全无关,是吗? 它们很容易被破坏并且容易出错。我宁愿让普通用户轻松访问它们。 别管安全相关,注册表写入经常会产生 LUA/UAC 问题,注册表很容易损坏等等。Microsoft 自己最近建议不要这样做,并支持 IsolatedStorage 或 Environment.SpecialFolder.ApplicationData这些原因。【参考方案6】:

我们使用自定义 SettingsProvider 将配置信息存储在应用程序数据库的表中。如果您已经在使用数据库,这是一个很好的解决方案。

【讨论】:

【参考方案7】:

在 Chris Sells 和 Ian Griffiths 编写的 Programming WPF 中说

WPF 应用程序的首选设置机制是 .NET 和 VS 提供的一种:System.Configuration 命名空间中带有内置设计器的 ApplicationSettingBase 类。

【讨论】:

不幸的是,设置设计器(在 vs2008 中)将您在设计器中设置的任何设置具体化为 settings.Designer.vb 中的 DefaultSettingValueAttribute 条目。似乎没有办法关闭它。如果您手动编辑配置文件,那么下次您在设置设计器中进行编辑时,它将重新同步。这太糟糕了。这可能会导致应用程序使用硬编码的默认值(有些隐藏)进行部署,如果 app.config 设置丢失,它将采取行动。 tinyurl.com/3xyzz66

以上是关于存储 UI 设置的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS 最佳实践,存储在隐藏字段、状态、本地存储中?

最佳实践:我应该如何在 C#(格式/类型)中存储设置?

在 Win32 Delphi 应用程序中存储用户首选项和设置的最佳实践是啥?

UIViewController 最佳实践——加载

iOS 测试推送通知的最佳实践(UI 测试)

使用常量数据反应最佳实践