【问题标题】:ReactiveCommand never hooks up the event handler for the canExecute observableReactiveCommand 永远不会为 canExecute observable 连接事件处理程序
【发布时间】:2015-11-13 13:36:44
【问题描述】:

在我的测试用例中,我可以验证事件处理程序CollectionChanged 是否正确连接。创建命令时会发生这种情况。在我的视图模型中,当我做同样的事情时,事件处理程序永远不会连接。这是为什么呢?

如果我在我的视图模型中显式调用Undo.CanExecute(null),它将连接事件处理程序。我想我不应该这样做,而且我的视图模型代码一定有问题。

查看模型

ActionManager = new ActionManager();    

var canUndo = Observable
    .FromEventPattern(e => ActionManager.CollectionChanged += e, e => ActionManager.CollectionChanged -= e)
    .Select(_ => ActionManager.CanUndo)
    ;

Undo = ReactiveCommand.CreateAsyncTask(canUndo, UndoAsync);

测试用例

public class MiscTests
{
    [Fact]
    public void CanExecute()
    { 
        var am = new ActionManager();
        var canUndo = Observable
            .FromEventPattern(e => am.CollectionChanged += e, e => am.CollectionChanged -= e)
            .Select(_ => am.CanUndo);

        var command = ReactiveCommand.Create(canUndo);

        var action = new CallMethodAction(() => { }, () => { });
        var canExecute = command.CanExecute(null);
        canExecute.Should().BeFalse();
        am.Execute(action);
        canExecute = command.CanExecute(null);
        canExecute.Should().BeTrue();

    }
}

【问题讨论】:

    标签: system.reactive reactiveui


    【解决方案1】:

    别担心,您的视图模型代码很可能是正确的。

    您设法观察到的是 Rx observables 在行动中的惰性。挖掘ReactiveCommand constructor的源代码发现,你提供给CreateAsyncTask工厂方法的canExecute observable并没有立即订阅,而是Publish is called,它返回IConnectableObservable,它存储在一个私有字段(this.canExecute )。因此,ReactiveCommand 开始实际监听 canExecute 的变化,当 Connectthis.canExecute 调用时。这发生在CanExecute(object parameter) method

    那么,您是否应该在 ViewModel 中显式调用 ReactiveCommand's CanExecute ?不,因为当您将命令绑定到实际按钮时,这应该由您的 View 框架完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 2019-12-14
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 2014-12-29
      相关资源
      最近更新 更多