存储 UI 设置的最佳实践?

发布于 2024-07-07 17:19:51 字数 330 浏览 9 评论 0原文

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

  • Expander States
  • 菜单订单
  • Sizing Properties
  • 等...

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

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

we're currently planning a larger WPF LoB application and i wonder what others think being the best practice for storing lots of UI settings e.g.

  • Expander States
  • Menu orders
  • Sizing Properties
  • etc...

i don't like the idea of having dozens of stored values using the delivered SettingsProvider (i.e. App.config file) although it can be used to store it in an embedded database using a custom SettingsProvider.
being able to use some kind of databinding is also a concern.
Has anyone had the same problems?

What did you do to store lots of ui user settings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

黯淡〆 2024-07-14 17:19:51

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

Environment.SpecialFolder.ApplicationData

将其存储为 xml“首选项”文件,这样如果它被损坏,访问和更改并不困难。

到目前为止,这对我们来说比注册表要好得多,如果有任何内容损坏或需要重置,它会更干净且更容易被破坏。

We store the preferences file here:

Environment.SpecialFolder.ApplicationData

Store it as xml "preferences" file so it's not so hard to get to and change if it ever gets corrupted.

So far this has worked much better than the registry for us, it's cleaner and easier to blow out if anything gets corrupted or needs to be reset.

御守 2024-07-14 17:19:51

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

这样做的问题是,如果您的应用程序很大,它很快就会变得一团糟。

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

The quicker way to store UI settings is using the Properties.Settings.Default system. What can be nice with it is to use WPF binding to the value. Example here. Settings are automatically updated and loaded.

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

The problem with that is that it quickly becomes a mess if your application is large.

Another solution (proposed by someone here) is to use the ApplicationData path to store your own preferences into XML. There you can build your own setting class and use the XML serializer to persist it. This approach enables you to do migration from versions to versions. While being more powerful, this method requires a bit more code.

浮云落日 2024-07-14 17:19:51

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

Digging into aogan's answer and combining it with decasteljau's answer and the blog post he referenced, here is an example that fills in some gaps that weren't clear to me.

The xaml file:

<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}"
    ...

And the source file:

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; }
        }
    }
}
余生共白头 2024-07-14 17:19:51

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

We store all in the Isolation Storage (we are running with ClickOnce). We have some object that we serialize (XmlSerializer).

夜未央樱花落 2024-07-14 17:19:51

似乎由于某种原因失去了人气; 但注册表始终是进行此类设置的合适位置。

Seems to be losing popularity for some reason; but the registry has always been an appropriate place for these kinds of settings.

污味仙女 2024-07-14 17:19:51

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

We use a custom SettingsProvider to store the config information in a table in the app's database. This is a good solution if you're already using a database.

偏爱自由 2024-07-14 17:19:51

在 Chris Sells 编写的《WPF 编程》中 Ian Griffiths 表示,

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

In the Programming WPF by Chris Sells & Ian Griffiths it says

The preferred setting mechanism for WPF application is the one provided by .NET and VS: the ApplicationSettingBase class from the System.Configuration namespace with the built-in designer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文