应用程序设置绑定最佳实践

Posted

技术标签:

【中文标题】应用程序设置绑定最佳实践【英文标题】:Application settings binding best practices 【发布时间】:2017-05-25 10:50:59 【问题描述】:

我一直在努力研究如何最好地与 WinRT/UWP 应用程序中绑定级别的设置“交互”。我一直在寻找这方面的最佳实践,但我还没有找到明确的答案。到目前为止,我在我的应用中所做的如下:

    定义一个实现 INotifyPropertyChanged 的​​ BindableBase。

    创建一个继承自 BindableBase 的 AppSettings 类,看起来有点像这样:

    public class AppSettings : BindableBase
    
        ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
    
        public string MySetting
        
            get
            
                if (!localSettings.Values.ContainsKey("MySetting"))
                    localSettings.Values["MySetting"] = "Some default value";
    
                return localSettings.Values["MySetting"].ToString();
            
            set
            
                localSettings.Values["MySetting"] = value;
                RaisePropertyChanged();
            
        
    
    

    定义一个具有 AppSettings 属性的 ViewModel:

    public class SettingsViewModel
    
        public AppSettings Settings  get; set;  = new AppSettings();
    
    

    绑定到视图中的设置属性:

    <TextBlock Text="Binding Settings.MySetting, Mode=TwoWay">
    

我过去曾见过并使用过具有设置服务的实现,但这些应用程序不需要更改设置即可立即生效。所以我基本上要问的是:如果对设置的更改应该立即生效,那么上述实现是绑定到设置的好方法吗?如果没有,你有什么推荐的?

【问题讨论】:

相关:Best practice zombies 另外,可以使用您的意思进行澄清生效。你的意思是立即得救?我知道对于 WPF,框架中没有任何东西可以为您做任何事情。你似乎已经有了一些应该工作的东西(ish?)。如果它不能满足您的需求,请更改代码以使其正常运行。 我认为您的实现很好,并且可以根据您的情况进行操作。如果您需要立即应用每个设置(而不是单击保存按钮),那么您必须在属性集中分配新值(就像您一样)。届时将触发任何订阅的属性集更改的侦听器。 @Will 我不是在寻找最佳实践,但如果我的实现有问题,因为我觉得它在性能方面效率不高。 你觉得?或者你知道吗?不要感觉。获取一个工具(不要问,我没有),它可以衡量性能并确定可以改进的地方。我们所能做的就是猜测。 【参考方案1】:

这篇文章给我很大启发,所以我想出了一些更优雅的东西,以避免多次复制和粘贴属性名称(键)。我使用以下内容:

public class SettingsViewModel : BindableBase

    public string MyProperty
    
        get
        
            return Get("MyProperty", "SomeDefaultValue");
        
        set
        
            Set("MyProperty", value);
        
    

    public T Get<T>(string PropertyName, T DefaultValue)
    
        //If setting doesn't exist, create it.
        if (!App.Settings.ContainsKey(PropertyName))
            App.Settings[PropertyName] = DefaultValue;

        return (T)App.Settings[PropertyName];
    

    public void Set<T>(string PropertyName, T Value)
    
        //If setting doesn't exist or the value is different, create the setting or set new value, respectively.
        if (!App.Settings.ContainsKey(PropertyName) || !((T)App.Settings[PropertyName]).Equals(Value))
        
            App.Settings[PropertyName] = Value;
            OnPropertyChanged(PropertyName);
        
    

假设您的 App 类定义了以下属性:

public static IPropertySet Settings

    get
    
        return Windows.Storage.ApplicationData.Current.LocalSettings.Values;
    

后者比写方便,

ApplicationData.Current.LocalSettings.Values

并且仍然可以全局访问。

【讨论】:

【参考方案2】:

这在一般情况下似乎很好。我唯一要更改的是仅在数据实际更改时才发出通知:

set

    if (MySetting != value)
    
        localSettings.Values["MySetting"] = value;
        RaisePropertyChanged();
    

这将避免不必要地发出通知。 根据读取值的频率,您可能希望将自己的设置值副本保存在内存中(在私有字段中),而不是每次都从容器中读取它们。

【讨论】:

将值存储在私有字段中,并且仅在发生更改时才更改 ApplicationData,这在性能方面确实会更好一些。至于我的 RaisePropertyChanged 实现,如果我没记错的话,它已经检查了设置是否发生了变化,但我会检查以确保。

以上是关于应用程序设置绑定最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

Java 数据绑定最佳实践

WPF 数据绑定和验证规则最佳实践

使用 RxSwift 将 UITableViewCell 中的控件绑定到 ViewModel 的最佳实践

Combine + SwiftUI 中的最佳数据绑定实践?

域名绑定动态IP最佳实践

域名绑定动态IP最佳实践