【问题标题】:Delayed display of a UI control after execution of ReactiveCommand执行 ReactiveCommand 后 UI 控件的延迟显示
【发布时间】:2018-07-05 08:38:42
【问题描述】:

我有一个基于信号执行的响应式命令 readCommand

IObservable<Unit> readSignal = ...

readSignal.InvokeCommand(readCommand);

命令的结果显示在用户控件中,比如TextBox

我想在TextBox 旁边放置一个refresh button,单击它会调用readCommand。该按钮在命令执行时不可见,然后在命令执行 5 秒后可见。

接下来我尝试显示/隐藏refresh buttonIsRefreshable 链接到refresh buttonVisibility 属性。

readCommand
    .IsExecuting
    .SelectMany(x => (x ? Observable.Timer(TimeSpan.FromMilliseconds(0)) : Observable.Timer(refreshTimeout)).Select(_ => !x))
    .ToPropertyEx(this, vm => vm.IsRefreshable, false, false, RxApp.MainThreadScheduler);

readSignal 的发射率低于刷新率 (refreshTimeout) 时,我认为它工作正常。但如果readSignal 的速率快于refreshTimeout,则显然不起作用。

【问题讨论】:

  • 在您的SelectMany 之后尝试输入.Switch() 运算符。我怀疑你有一个IObservable&lt;IObservable&lt;T&gt;&gt;,需要减少到最新的内部IObservable&lt;T&gt;
  • @Enigmativity 是的,它似乎工作正常。唯一的变化是SelectMany 需要替换为SelectSelectMany 将其展平,而 Select 返回 IObservable&lt;IObservable&lt;bool&gt;&gt;。我也通过以下方式解决了它,但您的解决方案很优雅。介意把它作为答案吗?所以其他人很容易找到它,而不是依赖这里的 cmets。 readCommand.IsExecuting.Where(x =&gt; !x).Select(x =&gt; Observable.Timer(refreshTimeout)).Switch().Select(x =&gt; true).Merge(readCommand.IsExecuting.Where(x =&gt; x).Select(x =&gt; !x)).ToPropertyEx(...);

标签: system.reactive reactiveui rx.net


【解决方案1】:

使用SelectMany,您可以通过合并所有内部可观察对象将IObservable&lt;IObservable&lt;T&gt;&gt; 转换为IObservable&lt;T&gt; - 这意味着所有计时器都会触发,从而导致不需要的行为。

SelectMany 实际上与 Select/Merge 组合相同。

您需要的只是从最新的内部可观察对象中生成值。为此,您需要一个 Select/Switch 组合。

试试这个:

readCommand
    .IsExecuting
    .Select(x => x
        ? Observable.Timer(TimeSpan.FromMilliseconds(0))
        : Observable.Timer(refreshTimeout).Select(_ => !x))
    .Switch()
    .ToPropertyEx(this, vm => vm.IsRefreshable, false, false, RxApp.MainThreadScheduler);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2013-02-22
    • 2013-11-11
    相关资源
    最近更新 更多