我想知道绑定到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>
Run Code Online (Sandbox Code Playgroud)
更新
我发现了这个:https: //github.com/reactiveui/rxui-design-guidelines
并认为我应该能够做到这样的事情:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty(this, x => x.IsLoading);
Run Code Online (Sandbox Code Playgroud)
但它给出了编译错误:
方法'ReactiveUI.OAPHCreationHelperMixin.ToProperty <TObj,TRet>的类型参数(System.IObservable <TRet>,TObj,System.Linq.Expressions.Expression <System.Func <TObj,TRet >>,TRet,System.Reactive. Concurrency.IScheduler)'无法从用法中推断出来.尝试显式指定类型参数.
我也尝试过:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty<TheViewModel, bool>(this, x => x.IsLoading);
Run Code Online (Sandbox Code Playgroud)
但得到编译错误:
'System.IObservable <System.IObservable <bool >>'不包含'ToProperty'的定义和最佳扩展方法重载'ReactiveUI.OAPHCreationHelperMixin.ToProperty <TObj,TRet>(System.IObservable <TRet>,TObj,System .Linq.Expressions.Expression <System.Func <TObj,TRet >>,TRet,System.Reactive.Concurrency.IScheduler)'有一些无效的参数
和
实例参数:无法从'System.IObservable>'转换为'System.IObservable'
原来下面
我的帖子末尾列出的代码通过访问IsLoading属性来进行初始绑定,听起来就像启动订阅一样.但是从进一步的阅读来看,我似乎应该使用它WhenAny,我似乎无法弄清楚我的鼻子前面放了什么:
ToProperty和BindTo - 获取初始值而无需订阅
添加:
this.WhenAnyValue(x => x.LoadCommand.IsExecuting);
Run Code Online (Sandbox Code Playgroud)
也有效,但还有更好的方法吗?
我正在考虑删除ObservableAsPropertyHelper它,因为它似乎没有为我做太多,并使IsLoading正常的属性,如:
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { this.RaiseAndSetIfChanged(ref _isLoading, value); }
}
Run Code Online (Sandbox Code Playgroud)
并执行类似下面的操作,但它不会编译,因为它试图将IObservable< bool>一个bool 分配给:
this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.Subscribe(x => IsLoading = x);
Run Code Online (Sandbox Code Playgroud)
当前代码:
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();
Run Code Online (Sandbox Code Playgroud)
并认为我应该能够做到这样的事情:
你有正确的想法,但语法有点偏,尝试:
this.LoadCommand.IsExecuting
.ToProperty(this, x => x.IsLoading, out _isLoading);
Run Code Online (Sandbox Code Playgroud)
如果你要对可以改变的对象(即你有一个长表达式)这样做,那么WhenAnyObservable你可以使用一种特殊的方法来代替WhenAnyValue:
this.WhenAnyObservable(x => x.SomeObjectThatMightBeReplaced.IsExecuting)
.ToProperty(this, x => x.IsLoading, out _isLoading);
Run Code Online (Sandbox Code Playgroud)
我以前遇到过这个问题,我想你所经历的就在这里。
ToProperty / OAPH 变更
ObservableAsPropertyHelper 本身不再是 IObservable,使用 WhenAny 来观察它。
ObservableAsPropertyHelper 现在仅在第一次读取 Value 时延迟订阅源。这显着提高了性能和内存使用率,但代价是“为什么我的测试不起作用?” 困惑。如果您发现您的 ToProperty“不起作用”,这可能就是原因。
它是惰性的,因此您必须订阅它(即,如果使用 OAPH,则从属性请求一个值)才能使其工作。这就是为什么您注意到您var startSubscription = IsLoading;“解决”了问题。
知道这一点让我更容易确定这是否是一个问题,或者只是在单元测试期间需要记住的事情,知道在我的应用程序中这些属性将被绑定并因此被订阅,使其毫无意义实践。你知道,整个“树倒在森林里,没有人听到”的想法。
我认为你应该坚持ToProperty现有的,恕我直言,这似乎是正确的方法。
| 归档时间: |
|
| 查看次数: |
1973 次 |
| 最近记录: |