我有个 AppSettingsManager
静态类,这个类能够监视 .json 配置文件的改动,并实时重载配置,重载的配置立即反序列化并赋予 Settings
这个属性。我使用 .Net Core/WPF,别问我为什么不用 DI、Configuration 等新技术。。。我不太会,并且这些技术结合起来用会让我的项目无法实现某些功能比如用了自带的DI,我不知道如何给 View 通过 XAML 设置DataContext(VM)(前台设置上下文才可以利用智能感知访问VM);又比如,.Net Core 的 Configuration 无法运行时保存。。。回到问题:
public static class AppSettingsManager
{
public static AppSettings Settings { get; private set; }
// 略去其余代码。
}
VM:
// 我使用 Fody/PropertyChanged 来自动实现属性通知
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
public AppSettings MySettings => AppSettingsManager.Settings;
// 省略其余代码。
}
V:
<TextBlock Text="{Binding MySettings.X, Mode=OneWay}" />
现在,程序在启动后,TextBlock
能正确显示 X
值,如果我修改配置文件,AppSettingsManager
将检测到,并且重新读取配置文件,Settings
属性将被重新赋值,按理讲 MySettings
也随之改变,TextBlock
应该得到更新,但实际 TextBlock
并没有更新!
把通知接口附加到 AppSettings 类,检测到文件修改后重新赋值 AppSettings 的相关属性而不是用新对象替换。
WPF 注册的变更通知仅针对直接绑定关联的属性,间接依赖的对象 WPF 根本不关心。
在这里 WPF 只关心 X 有没有变,AppSettings 有没有变无所谓。如果 X 被注册了通知,你直接把 AppSettings 换了反而会导致内存泄漏。
我确信你说的是对的!<(^-^)>
我现在也给 AppSettings
类添加了 [AddINotifyPropertyChangedInterface]
特性,现在它具有了属性通知能力。
同时,我按照你的做法,重新赋予 Settings
的各个属性的新值而不是直接替换它。
我很懒,所以我找到了通用的自动替换属性的代码:
使用反射在两个对象之间进行属性复制
完美!