无法使简单的ReactiveUI示例工作

时间:2018-02-16 10:27:49

标签: c# winforms reactiveui

我刚刚开始学习ReactUI并试图关注此示例:https://www.codeproject.com/Articles/801986/Using-ReactiveUI-for-WinForms-MVVM-Design 我开始感到沮丧,因为我无法让它工作。这是代码问题(从样本中复制):

//
// ViewModel example
//
namespace WinFormMVVM.ViewModels
{
    public class HomeViewModel : ReactiveUI.ReactiveObject
    {
        string ModelString;
        public string EnteredText
        {
            get { return ModelString; }
            set { this.RaiseAndSetIfChanged( ref ModelString, value);}
        }

        string statusString = "";
        public string Status
        {
            get{return statusString;}
            set{this.RaiseAndSetIfChanged(ref statusString,value);}
        }

        public ReactiveCommand<object> OKCmd { get; private set; }

        public HomeViewModel
        {
            var OKCmdObs = this.WhenAny(vm => vm.EnteredText, 
                s => !string.IsNullOrWhiteSpace(s.Value));
            OKCmd = ReactiveCommand.Create(OKCmdObs);           // <--- Trouble starts here
            OKCmd.Subscribe(_=> Status = EnteredText + " is saved.");
        }
    }
}

我标记了相关的行。 编译此代码会导致此错误:

Error CS1503 Argument 1: cannot convert from 'System.IObservable<bool>' to 'System.Action'

我使用ReactiveUI for WinForms版本7.4.0(这似乎是最新的稳定版本)

github上的ReactiveUI示例告诉我使用ReactiveCommand.CreateAsyncTask(...)这是一种未知方法。这真是令人沮丧......

有人可以解释如何使样本发挥作用。

3 个答案:

答案 0 :(得分:1)

所有ReactiveCommand工厂方法都接受ActionFunc<T>作为定义执行命令时要执行的操作的第一个参数。下一个参数是您要查找的设置CanExecute的参数。使代码更改

OKCmd = ReactiveCommand.Create(OKCmdObs);

OKCmd = ReactiveCommand.Create(() => { /* Do nothing */ }, OKCmdObs);

你可能也应该改变

public ReactiveCommand<object> OKCmd { get; private set; }

public ReactiveCommand<Unit, Unit> OKCmd { get; private set; }

Unit是一种用于表示没有实际价值的类型,只是一个信号。

本教程看起来像是使用RxUI v6.x,它的语法与ReactiveCommand的v7.x略有不同。您可以在此处阅读ReactiveCommandhttps://reactiveui.net/docs/handbook/commands/

答案 1 :(得分:0)

我终于得到了样本。作为其他人的参考,我必须做的改变:

//
// ViewModel example
//
namespace WinFormMVVM.ViewModels
{
    public class HomeViewModel : ReactiveUI.ReactiveObject
    {
        string ModelString;
        public string EnteredText
        {
            get { return ModelString; }
            set { this.RaiseAndSetIfChanged( ref ModelString, value);}
        }

        string statusString = "";
        public string Status
        {
            get{return statusString;}
            set{this.RaiseAndSetIfChanged(ref statusString,value);}
        }

        public ReactiveCommand<object> OKCmd { get; private set; }

        public HomeViewModel
        {
            var OKCmdObs = this.WhenAny(vm => vm.EnteredText, 
                                        s => !string.IsNullOrWhiteSpace(s.Value));

            // OKCmd = ReactiveCommand.Create(OKCmdObs);    
            // OKCmd.Subscribe(_=> Status = EnteredText + " is saved.");

            OKCmd = ReactiveCommand.CreateFromObservable(() => {
                Status = EnteredText + " is saved.";
                return Observable.Return(true);
            }, OKCmdObs);
        }
    }
}

答案 2 :(得分:0)

好的,这似乎对我有用:

public class HomeViewModel : ReactiveObject
{
    private string ModelString;

    public string EnteredText
    {
        get { return ModelString; }
        set { this.RaiseAndSetIfChanged(ref ModelString, value); }
    }

    private string statusString = string.Empty;

    public string Status
    {
        get { return statusString; }
        set { this.RaiseAndSetIfChanged(ref statusString, value); }
    }

    public ReactiveCommand<System.Reactive.Unit, bool> OKCmd { get; private set; }

    public HomeViewModel()
    {
        var OkCmdObs = this.WhenAny(vm => vm.EnteredText,
            s => !string.IsNullOrWhiteSpace(s.Value));
        OKCmd = ReactiveCommand.CreateFromObservable(() =>
        {
            Status = EnteredText + " is saved.";
            return Observable.Return(true);
        }, OkCmdObs);
    }
}

注意,这是带有ReactiveUI v10.1.5的VS2019