我刚刚开始学习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(...)
这是一种未知方法。这真是令人沮丧......
有人可以解释如何使样本发挥作用。
答案 0 :(得分:1)
所有ReactiveCommand
工厂方法都接受Action
或Func<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略有不同。您可以在此处阅读ReactiveCommand
:https://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