WPF 绑定 VM 中引用了静态类属性的只读属性无法得到通知更新?

2020-03-28 08:20发布

问题:

我有个 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 并没有更新!

回答1:

把通知接口附加到 AppSettings 类,检测到文件修改后重新赋值 AppSettings 的相关属性而不是用新对象替换。
WPF 注册的变更通知仅针对直接绑定关联的属性,间接依赖的对象 WPF 根本不关心。
在这里 WPF 只关心 X 有没有变,AppSettings 有没有变无所谓。如果 X 被注册了通知,你直接把 AppSettings 换了反而会导致内存泄漏。