如何将这两个命令合二为一?

How do I combine these two commands into one?

在我的 class 正文中,我有这行代码:

private ReactiveCommand<object> _displayCommand = ReactiveCommand.Create();

在class构造函数中,我设置了一个订阅:

_displayCommand.Subscribe(_ =>
{
    MessageBox.Show("Button clicked.");
});

是否可以编写某种扩展方法来有效地将这两个命令合二为一,因此通过单个函数调用我们可以同时调用两个 ReactiveCommand.Create(),并使用 Reactive Extensions 创建订阅( RX)?

这会将所有逻辑相关的代码组合在一起,并使 ViewModel 更加简洁。

更新

这是我目前所拥有的(感谢@jt000):

public static ReactiveCommand<object> CreateAndSubscribe(Func<object> fn)
{
    var displayCommand = ReactiveCommand.Create();
    displayCommand.Subscribe<object>(_ => fn.Invoke());
    return displayCommand;
}

private ReactiveCommand<object> _displayCommand = CreateAndSubscribe(() =>
{
    return MessageBox.Show("Hello");
});

public ReactiveCommand<object> DisplayCommand
{
    get { return _displayCommand; }
    protected set { _displayCommand = value; }
}

但是,我偶尔需要在 displayCommand.Subscribe(fn) 之间插入调用 .Buffer(TimeSpan.FromSeconds(1).,而这个函数不够通用,无法做到这一点。我真正需要的是某种将整个订阅传递给 CreateAndSubscribe 的方法——也许一些 Func 需要一个 IObservable?

这意味着我可以使用类似下面的函数调用:

private ReactiveCommand<object> _displayCommand = 
    CreateAndSubscribe(o => o.Subscribe(() =>
                              {
                                  return MessageBox.Show("Hello");
                              }));

如果我想插入 .Buffer(TimeSpan.FromSeconds(1)):

private ReactiveCommand<object> _displayCommand = 
    CreateAndSubscribe(o => o.Buffer(TimeSpan.FromSeconds(1)).Subscribe(() =>
                              {
                                  return MessageBox.Show("Hello");
                              }));

这行得通吗?

public static ReactiveCommand<object> CreateAndSubscribe(Func<object> fn) 
{
    var displayCommand = ReactiveCommand.Create();
    displayCommand.Subscribe(fn);
    return displayCommand;
}

用法:

CreateAndSubscribe(_ => MessageBox.Show("hi"));

是的,但没有多大意义,因为定义字段时实例成员不在范围内。您传递给 Subscribe 的处理程序不能引用任何视图模型的字段或调用它的任何方法。除了示例中显示的内容,您将无法做更多的事情,例如调用 MessageBox.Show 或类似的东西。

将这样的东西放在静态 class 中。

   public static void CreateAndSubscribe(this displayCommand)
    {
        displayCommand = ReactiveCommand.Create();
        displayCommand.Subscribe(_ =>
        {
            MessageBox.Show("Button clicked.");
        });
    }

像任何其他扩展方法一样访问它:

_displayCommand.CreateAndSubscribe();

这个API其实是故意漏掉的,因为Create到return两者没有优雅的办法ReactiveCommand IDisposable 来自 Create。您 可以 使用 out 参数做一些丑陋的事情,但最终会非常麻烦。

虽然我有时也会错过 CreateWithAction 或类似的东西,但直接的 Subscribe 有点破坏了 RxUI 的可组合性;这 API 使得 更难 将东西放在一起,而不是更容易。