如何在C#中更改运行时的可观察性



考虑使用两个具有不同密钥的SourceCaches

var sourceCacheA = new SourceCache<MyType, int>(x => x.Prop1);
var sourceCacheB = new SourceCache<MyType, string>(x => x.Prop2);

两者都连接在哪里:

var observableA = sourceCacheA.Connect();
var observableB = sourceCacheB.Connect();

假设observableAReadOnlyObservableCollection绑定如下:

observableA.ObserveOn(RxApp.MainThreadScheduler).Bind(out _targetCollection).Subscribe();

如何构建一个可在运行时更改的可观察对象,同时绑定到相同的_targetCollection

所以基本上,它应该这样操作:

if(somethingHappenBool)
{
**observableA**.ObserveOn(RxApp.MainThreadScheduler).Bind(out _targetCollection).Subscribe();
} 
else
{
**observableB**.ObserveOn(RxApp.MainThreadScheduler).Bind(out _targetCollection).Subscribe();
}

编辑:

根据Jason的回答,我提出了以下解决方案:

public enum SwitchDataSourceOption
{
SourceA,
SourceB
}
public SwitchDataSourceOption Option
{
get => _option;
set
{
_option = value;
NotifyPropertyChanged(nameof(Option));
}
}
sourceCacheA = new SourceCache<MyType, int>(x => x.AProp);
sourceCacheB = new SourceCache<MyType, int>(x => x.BProp);
this.WhenAnyValue(x => x.Option)
.Select(opt => opt == SwitchDataSourceOption.SourceA ? sourceCacheA : sourceCacheB)
.Switch()
.AsObservableCache()
.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _targetCollection)
.Subscribe();

然而,我不知道如何处理各种密钥类型,因为在我的原始示例中,我将intstring作为密钥

看起来您可以自己制作集合:

var collection = new ObservableCollectionExtended<MyType>();

并与绑定

observableA.Bind(collection);

因此,您不必使用绑定创建新的集合。


通常,当我想在运行时更改可观测值时,我会将更改可观测的事件视为可观测值本身。

我对ReactiveUI不太熟悉,但我怀疑您想要的行为可以通过以下代码解决:

var sourceCacheA = new SourceCache<MyType, int>(x => x.Prop1);
var sourceCacheB = new SourceCache<MyType, string>(x => x.Prop2);
var observableA = sourceCacheA.Connect();
var observableB = sourceCacheB.Connect();
// Some change stream
var somethingHappened = new Subject<bool>(); 
// Create observable collection manually
var collection = new ObservableCollectionExtended<MyType>();
// Project to Unit so that types are the same
var bindToA = observableA.Bind(collection).Select(_ => Unit.Default);
var bindToB = observableB.Bind(collection).Select(_ => Unit.Default);
// Create observable that unsubscribes from the current and subscribes to the other when something happens
var mergedObservable = somethingHappened
.StartWith(false)
.Select(s => s ? bindToA : bindToB)
.Switch();
// Begin monitoring changes
mergedObservable.Subscribe();
somethingHappened.OnNext(true);
sourceCacheA.Edit(i => i.AddOrUpdate(new [] {new MyType { Prop1 = 1}, new MyType { Prop1 = 2}}));
// Collection contains 2 elements
sourceCacheA.Edit(i => i.Clear()); 
// Collection contains 0 elements
somethingHappened.OnNext(false);
sourceCacheB.Edit(i => i.AddOrUpdate(new [] {new MyType { Prop1 = 0, Prop2 = "1"}, new MyType { Prop1 = 0, Prop2 = "2"}}));
// Collection contains 2 elements
// This is ignored as the observer is currently only listening to sourceCacheB
sourceCacheA.Edit(i => i.AddOrUpdate(new [] {new MyType { Prop1 = 1}, new MyType { Prop1 = 2}}));
// Collection contains previous 2 elements

注意:请注意,切换可能会错过取消订阅和订阅新可观察对象之间的事件。

相关内容

  • 没有找到相关文章

最新更新