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

时间:2015-01-04 23:09:23

标签: c# wpf system.reactive reactiveui

在我班级的课堂上,我有这行代码:

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

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

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

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

这会将所有逻辑相关的代码组合在一起,并使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; }
}

但是,我需要偶尔在.Buffer(TimeSpan.FromSeconds(1).displayCommand之间插入电话.Subscribe(fn),此功能不够通用。我真正需要的是将整个订阅传递到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");
                              }));

4 个答案:

答案 0 :(得分:3)

这个API实际上是故意丢失的,因为Create没有优雅的方式让返回 ReactiveCommand {{1来自IDisposable的结果。你可以Create参数做一些丑陋的事情,但它最终会非常麻烦。

虽然我肯定有时会错过out或类似的东西,但是直接CreateWithAction有点打败了RxUI的可组合性方面;这个API使得更难将内容放在一起,而不是更容易。

答案 1 :(得分:2)

这会有用吗?

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

用法:

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

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

_displayCommand.CreateAndSubscribe();