C# 存储UI设置的最佳实践?

C# 存储UI设置的最佳实践?,c#,wpf,settings,appsettings,C#,Wpf,Settings,Appsettings,我们目前正在计划一个更大的WPF LoB应用程序,我想知道其他人认为存储大量UI设置的最佳实践是什么 扩展状态 菜单命令 上浆性能 等等 我不喜欢使用交付的SettingsProvider(即App.config文件)存储几十个值,尽管它可以使用自定义SettingsProvider将其存储在嵌入式数据库中。 能够使用某种数据绑定也是一个问题。 有人有过同样的问题吗 你做了什么来存储大量的用户界面设置?出于某种原因,似乎正在失去人气;但注册表始终是此类设置的合适位置。我们将首选项文件存储在此

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

  • 扩展状态
  • 菜单命令
  • 上浆性能
  • 等等
我不喜欢使用交付的SettingsProvider(即App.config文件)存储几十个值,尽管它可以使用自定义SettingsProvider将其存储在嵌入式数据库中。 能够使用某种数据绑定也是一个问题。 有人有过同样的问题吗


你做了什么来存储大量的用户界面设置?

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

我们将首选项文件存储在此处:

Environment.SpecialFolder.ApplicationData
将其存储为xml“首选项”文件,以便在其损坏时不难访问和更改


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

我们将所有内容存储在
隔离存储中(我们使用ClickOnce运行)。我们序列化了一些对象(XmlSerializer)。

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

在Chris Sells和Ian Griffiths的编程WPF中说


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

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

<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); 
}

...
受保护的覆盖无效(System.ComponentModel.CancelEventArgs e)
{ 
Settings.Default.Save();
基数(e);
}
问题是,如果应用程序很大,它很快就会变得一团糟


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

深入研究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}"
    ...

登记处绝对不再是正确的地方。注册表被破坏,不适当的使用可能导致安全问题,并可能违反LUA/UAC原则。嗯,UI设置几乎与安全无关,是吗?它们很容易被破坏并且容易出错。我更希望普通用户能够轻松访问它们。更不用说与安全相关的问题了,注册表编写经常会产生LUA/UAC问题,注册表很容易损坏,等等。微软自己也建议不要这样做,出于这些原因,支持使用IsolatedStorage或Environment.SpecialFolder.ApplicationData。不幸的是,设置设计器(在vs2008中)将您在设计器中设置的任何设置具体化为settings.designer.vb中的DefaultSettingValueAttribute项。似乎没有办法关掉这个。如果手动编辑配置文件,则下次在设置设计器中编辑时,它将重新同步。这太糟糕了。这可能会导致应用程序使用硬编码的默认值(有些隐藏)部署,如果app.config设置丢失,将采取措施。
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; }
        }
    }
}