首页 新闻 会员 周边

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

0
悬赏园豆:20 [已解决问题] 解决于 2020-03-28 08:42

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

CodingNinja的主页 CodingNinja | 初学一级 | 园豆:157
提问于:2020-03-27 23:12
< >
分享
最佳答案
1

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

收获园豆:20
coredx | 小虾三级 |园豆:678 | 2020-03-28 05:10

我确信你说的是对的!<(^-^)>
我现在也给 AppSettings 类添加了 [AddINotifyPropertyChangedInterface] 特性,现在它具有了属性通知能力。
同时,我按照你的做法,重新赋予 Settings 的各个属性的新值而不是直接替换它。
我很懒,所以我找到了通用的自动替换属性的代码:
使用反射在两个对象之间进行属性复制

完美!

CodingNinja | 园豆:157 (初学一级) | 2020-03-28 08:42
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册