ReactiveUI中能否将对象作为属性使用?现有实现无变更通知
嘿,当然可以在ReactiveUI里用对象作为属性啦!你的代码大方向是对的,但有几个小问题导致你没收到变更通知,我帮你拆解一下:
1. 订阅逻辑里的参数误用
你这段代码里有个明显的小错误:
this.WhenAnyValue(x => x.Settings) .SelectMany(async x => await _settingsService.CreateSetting(Settings)) .Subscribe());
注意看SelectMany里的委托,你用了Settings(当前类的属性),但其实应该用传入的参数x——这个x才是WhenAnyValue传递过来的最新的Settings对象。你现在的写法不管Settings属性怎么变,都在传递同一个旧值,自然会让你误以为没收到通知。
修正后应该是:
this.WhenAnyValue(x => x.Settings) .SelectMany(async newSettings => await _settingsService.CreateSetting(newSettings)) .Subscribe());
2. 搞清楚你要监听的是「对象引用变化」还是「对象内部属性变化」
RaiseAndSetIfChanged只会在Settings的整个引用被替换时触发通知——比如你执行Settings = new Settings();或者给它赋值另一个已存在的Settings实例。如果只是修改现有Settings对象内部的属性(比如Settings.Theme = "Dark";),而没有替换整个对象,那么WhenAnyValue(x => x.Settings)是不会有任何反应的。
如果需要监听Settings内部属性的变化,你得把监听路径指向具体的内部属性:
// 监听Settings里的Theme属性变化 this.WhenAnyValue(x => x.Settings.Theme) .Subscribe(newTheme => { /* 处理主题变化逻辑 */ });
要是想监听Settings对象的任意内部属性变化,可以组合使用WhenAnyValue和SelectMany:
this.WhenAnyValue(x => x.Settings) // 监听Settings里的Property1和Property2变化 .SelectMany(settings => settings.WhenAnyValue(s => s.Property1, s => s.Property2)) .Subscribe(_ => { /* 处理任意内部属性变化 */ });
3. 别忘了让ViewModel继承ReactiveObject
这是最容易忽略的基础!如果你的ViewModel类没有继承ReactiveObject,那么RaiseAndSetIfChanged方法根本没办法正确触发INotifyPropertyChanged事件,自然不会有任何变更通知。你的类结构应该是这样的:
public class YourViewModel : ReactiveObject { private Settings settings; public Settings Settings { get { return settings; } set { this.RaiseAndSetIfChanged(ref settings, value); } } // 其他业务代码... }
先修正这几个点,应该就能正常收到变更通知啦!
内容的提问来源于stack exchange,提问作者Post Impatica

