我想知道绑定到ReactiveCommand的IsExecuting
的推荐方法。
问题是初始命令执行(在构造函数结束时启动)没有使用IsLoading
作为绑定更新WPF控件,尽管后续调用按预期工作。
更新2添加测试绑定代码
这会显示IsLoading
为真时的装饰内容
<ac:AdornedControl IsAdornerVisible="{Binding IsLoading}">
<ac:AdornedControl.AdornerContent>
<controls1:LoadingAdornerContent/>
</ac:AdornedControl.AdornerContent>
<fluent:ComboBox
ItemsSource="{Binding Content, Mode=OneWay}"
DisplayMemberPath="Name"
SelectedValuePath="ContentId"
SelectedValue="{Binding SelectedContentId}"
IsSynchronizedWithCurrentItem="True"
/>
</ac:AdornedControl>
更新
我发现了这个: https://github.com/reactiveui/rxui-design-guidelines
并且认为我应该可以做类似的事情:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty(this, x => x.IsLoading);
但它给出了编译错误:
方法的类型参数 “ReactiveUI.OAPHCreationHelperMixin.ToProperty&LT; TObj,TRet&gt;(System.IObservable&lt; TRet&gt;,TObj, System.Linq.Expressions.Expression&LT; System.Func&LT; TObj,TRet&gt;&gt;,TRet, System.Reactive.Concurrency.IScheduler)'无法从中推断出来 用法。尝试明确指定类型参数。
我也尝试过:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty<TheViewModel, bool>(this, x => x.IsLoading);
但是得到了编译错误:
“System.IObservable&LT; System.IObservable&LT; bool&gt;&gt;'不包含 'ToProperty'的定义和最佳扩展方法重载 “ReactiveUI.OAPHCreationHelperMixin.ToProperty&LT; TObj,TRet&gt;(System.IObservable&lt; TRet&gt;,TObj, System.Linq.Expressions.Expression&LT; System.Func&LT; TObj,TRet&gt;&gt;,TRet, System.Reactive.Concurrency.IScheduler)'有一些无效的参数
和
实例参数:无法转换 'System.IObservable&GT;'至 'System.IObservable'
原文
我的帖子末尾列出的代码通过访问IsLoading
属性来进行初始绑定,听起来就像启动订阅一样。但是从进一步的阅读来看,似乎我应该使用WhenAny
而我似乎无法弄清楚我的鼻子前面放了什么:
ToProperty and BindTo - Get initial value without Subscribing
添加:
this.WhenAnyValue(x => x.LoadCommand.IsExecuting);
也有效,但还有更好的方法吗?
我在考虑删除ObservableAsPropertyHelper
,因为它似乎对我没有太大作用,并使IsLoading
成为普通属性,如:
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { this.RaiseAndSetIfChanged(ref _isLoading, value); }
}
执行类似下面的操作,但它没有编译,因为它试图将IObservable< bool>
分配给bool:
this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.Subscribe(x => IsLoading = x);
当前代码:
private readonly ObservableAsPropertyHelper<bool> _isLoading;
public bool IsLoading
{
get { return _isLoading.Value; }
}
LoadCommand = ReactiveCommand.CreateAsyncTask(async _ =>
{
//go do command stuff like fetch data from a database
}
LoadCommand.IsExecuting.ToProperty(this, x => x.IsLoading, out _isLoading);
//works if I have this line
var startSubscription = IsLoading;
LoadCommand.ExecuteAsyncTask();
答案 0 :(得分:7)
并且认为我应该可以做类似的事情:
你有正确的想法,但语法有点偏,请尝试:
this.LoadCommand.IsExecuting
.ToProperty(this, x => x.IsLoading, out _isLoading);
如果您使用可以更改的对象(即您已经有一个长表达式)来执行此操作,那么您使用的是WhenAnyObservable
而不是WhenAnyValue
的特殊方法:
this.WhenAnyObservable(x => x.SomeObjectThatMightBeReplaced.IsExecuting)
.ToProperty(this, x => x.IsLoading, out _isLoading);
答案 1 :(得分:3)
我之前遇到过这种情况,我认为你遇到的是谎言here。
ToProperty / OAPH更改
ObservableAsPropertyHelper本身不再是IObservable,使用WhenAny来观察它。
ObservableAsPropertyHelper现在懒惰只有在第一次读取Value时才订阅源。这显着提高了性能和内存使用率,但代价是“为什么我的测试工作没有?”#34;混乱。如果您发现您的ToProperty&#34;没有工作&#34;,这可能是原因。
它是懒惰的,所以你必须订阅它(即如果使用OAPH请求属性中的值)才能工作。这就是为什么你注意到你的var startSubscription = IsLoading;
修复了&#39;这个问题。
知道这让我更容易确定这是否是一个问题,或者只是在我的单元测试中要记住的事情,知道在我的应用程序中这些属性将被绑定并因此订阅,制作在实践中没有实际意义。你知道,整棵树落在森林里,没有人在那里听到它&#34;想法。
我认为你应该坚持使用ToProperty
,这似乎是恕我直言的方式。