c # Наблюдаемый предмет, горячий и холодный - PullRequest
0 голосов
/ 06 февраля 2019

У меня часто возникает ситуация, когда я хочу, чтобы элемент пользовательского интерфейса «наблюдал» за базовым значением - предположим, что я отображаю int - я хочу IObservable, на который я могу подписаться.

Я использовалпредмет внизу, так что я могу просто установить его.Это работает очень хорошо ... за исключением первого раза.Если я настрою тему, а затем подпишусь на нее, открыв новый элемент пользовательского интерфейса, он не вызовет последующий текст до следующего изменения.

Я в основном хочу что-то, что работает как предмет - но всегда и немедленно делает onNext последней ценности для любых новых подписчиков.

Я знаю, что могу написать такую ​​конструкцию самостоятельно - но, похоже, это общий случай использования - есть ли что-то стандартное, что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Если вы используете 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() => наблюдаемое свойство, которое вы можете привязать к пользовательскому интерфейсу

оба работают с INotifyPropertyChanged

0 голосов
/ 06 февраля 2019

Вы хотите, чтобы 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.

...