我经常遇到这样的情况:我希望UI元素“监视”基础值-假设我正在显示一个int-我希望我可以订阅一个IObservable。
我一直在下面使用主题,因此我可以对其进行设置。效果很好……除了第一次。如果我设置了主题-然后稍后通过打开一个新的UI元素来订阅它-它不会触发onnext直到下一次更改。
我基本上想要一种像主题一样的东西-但总是对所有新订阅者立即执行最新值的onNext。
我知道我可以自己编写这样的结构-但似乎是一个常见的用例-我缺少某些标准吗?
答案 0 :(得分:1)
您需要BehaviorSubject<T>
或ReplaySubject<T>
。
BehaviorSubject<T>
重播最近的单个值,并要求您在构造函数中提供一个初始值。
您可以这样使用它:
var bs = new BehaviorSubject<int>(0);
bs.Subscribe(x => Console.WriteLine(x));
bs.OnNext(42);
bs.Subscribe(x => Console.WriteLine(x));
这将向控制台输出0
,然后输出42
,然后42
。
ReplaySubject<T>
有点笼统。它允许您指定要重播的值的数量,但不强制您提供初始值。
var rs = new ReplaySubject<int>(1);
rs.Subscribe(x => Console.WriteLine(x));
rs.OnNext(42);
rs.Subscribe(x => Console.WriteLine(x));
这将产生42
,然后42
到控制台。
将此与标准Subject<T>
进行比较。
var s = new Subject<int>();
s.Subscribe(x => Console.WriteLine(x));
s.OnNext(42);
s.Subscribe(x => Console.WriteLine(x));
那只会产生42
。
答案 1 :(得分:-1)
如果您在UI中使用Rx,则应查看ReactiveUI。
它具有方便的扩展名.ToProperty
等:
_isValid = this.WhenAnyValue(x => x.Username, x => x.Password, (user, password) => !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password)).ToProperty(this, x => x.IsValid);
public bool IsValid => _isValid.Value;
这基本上就是您正在做的事情:
this.WhenAnyValue(x => x.Property)
=>可观察的属性obs.ToProperty()
=>可以绑定到UI的属性可见两者都与INotifyPropertyChanged