ReactiveUI是一个可组合的跨平台模型 - 视图 - 视图模型框架,适用于所有.NET平台,受功能性反应式编程的启发。它允许您在一个可读位置围绕功能表达想法,从用户界面抽象出可变状态,并提高应用程序的可测试性
很久以前,当计算机编程首次出现时,机器必须手动编程。如果技术人员以正确的顺序输入正确的机器代码序列,则生成的程序行为将满足业务要求。而不是告诉计算机如何完成它的工作,哪个容易出错并且过分依赖于程序员的无懈可击,为什么我们不告诉它它的工作是什么,让它把剩下的工作弄清楚了?
ReactiveUI的灵感来自功能反应式编程的范例,它允许您将用户输入建模为随时间变化的函数。这非常酷,因为它允许您从用户界面中抽象出可变状态,并在一个可读位置表达功能,同时提高应用程序可测试性。反应式编程乍一看看起来可怕而复杂,但描述反应式编程的最佳方法是考虑电子表格:
-三个单元格,A,B和C.
-C定义为A和B的总和。
-每当A或B发生变化时,C都会做出反应来更新自身。
这是反应式编程:更改会自动在整个系统中传播。欢迎来到编程范例的花生酱和果冻。有关详细信息,请观看此视频来自Xamarin Evolve会议 - 为什么您应该使用 Michael Stonis的反应式编程来构建更好的移动应用程序。
安装以下软件包以开始构建您自己的ReactiveUI应用程序。注意:某些特定于平台的软件包是必需的。这意味着在正确安装软件包之前,您的应用程序将无法按预期执行。有关详细信息,请参阅“ 安装文档”页面。
平台 | ReactiveUI包 | 版本 |
---|---|---|
.NET标准 | ReactiveUI | 9.16.9 |
ReactiveUI.Fody | 9.16.9 | |
单元测试 | ReactiveUI.Testing | 9.16.9 |
通用Windows | ReactiveUI | 9.16.9 |
WPF | ReactiveUI.WPF | 9.16.9 |
Windows窗体 | ReactiveUI.WinForms | 9.16.9 |
Xamarin.Forms | ReactiveUI.XamForms | 9.16.9 |
Xamarin.Essentials | ReactiveUI | 9.16.9 |
Xamarin.iOS | ReactiveUI.AndroidSupport | 9.16.9 |
Xamarin.Mac | ReactiveUI | 9.16.9 |
Tizen | ReactiveUI | 9.16.9 |
阿瓦隆尼亚 | Avalonia.ReactiveUI | 9.16.9 |
任何 | ReactiveUI.Validation | 9.16.9 |
假设您有一个文本字段,每当用户在其中键入内容时,您都希望发出搜索该查询的网络请求。
public interface ISearchViewModel
{
string SearchQuery { get; set; }
ReactiveCommand> Search { get; }
IEnumerable SearchResults { get; }
}
我们在这里以声明的方式描述了启用搜索命令的条件。现在我们的Command IsEnabled非常高效,因为我们只是在应该更改时更新场景中的UI。
var canSearch = this.WhenAnyValue(x => x.SearchQuery, query => !string.IsNullOrWhiteSpace(query));
ReactiveCommand具有对后台操作的内置支持,并保证此块只能一次运行一次,并且CanExecute将自动禁用,并且该属性IsExecuting将在其运行时进行相应设置。
Search = ReactiveCommand.CreateFromTask(_ => searchService.Search(this.SearchQuery), canSearch);
ReactiveCommands本身IObservables,其值是async方法的结果,保证到达UI线程。我们将获取后台操作加载的搜索结果列表,并将它们转换为声明为的SearchResults属性ObservableAsPropertyHelper。
_searchResults = Search.ToProperty(this, x => x.SearchResults);
从ReactiveCommand.CreateFromTask被管道传送到ThrownExceptionsObservable的任何异常。订阅允许您处理UI线程上的错误。
Search.ThrownExceptions.Subscribe(error => { /* Handle exceptions. */ });
每当搜索查询发生变化时,我们将等待一秒钟的“死时间”,然后自动调用subscribe命令。
this.WhenAnyValue(x => x.SearchQuery)
.Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
.InvokeCommand(Search);
ReactiveUI完全支持XAML标记绑定,但我们还提供更多功能。ReactiveUI Bindings适用于所有平台,包括Xamarin Native和Windows Forms,并且运行相同。这些绑定是强类型的,并且重命名ViewModel属性或UI布局中的控件而不更新绑定,构建将失败。
this.WhenActivated(cleanup =>
{
this.Bind(ViewModel, x => x.SearchQuery, x => x.TextBox)
.DisposeWith(cleanup);
this.OneWayBind(ViewModel, x => x.SearchResults, x => x.ListView)
.DisposeWith(cleanup);
this.BindCommand(ViewModel, x => x.Search, x => x.Button)
.DisposeWith(cleanup);
});
ReactiveUI.Fody包允许您使用Reactive属性修饰读写属性 - 负责属性更改通知的代码将在编译时自动注入属性设置器。我们使用Fody工具来完成这项神奇的工作。
public class ReactiveViewModel:ReactiveObject
{
[ Reactive ]
public string SearchQuery { get ; setter; }
}
上面的代码被编译成以下代码:
public class ReactiveViewModel:ReactiveObject
{ private string searchQuery ;
public string SearchQuery
{ get => searchQuery ;
set => 这个。RaiseAndSetIfChanged(ref searchQuery,value);
}
}
ReactiveUI.Validation提供了一系列函数来创建验证,以反应方式运行。对于那些需要验证,实现ISupportsValidation的ViewModel,然后将验证规则添加到ViewModel,最后绑定到View中的验证规则!有关详细信息,请参阅文档 该软件包是基于jcmm33工作创建的,由alexmartinezm维护。
// # ViewModel
// Search query must not be empty. The selector is the property
// name and the line below is a single property validator.
this.ValidationRule(
vm => vm.SearchQuery,
query => !string.IsNullOrWhiteSpace(query),
"Please, provide a non-empty search query!");
// # View
// Bind any validations which reference the SearchQuery property
// to the text of the QueryValidation UI control!
this.BindValidation(ViewModel, vm => vm.SearchQuery, view => view.QueryValidation.Text);
Xamarin.Forms,WinRT,UWP,Windows Forms,WPF和Avalonia Desktop应用程序支持基于模型的视图路由。IScreen为视图模型创建一个注册视图,并IRoutableViewModel通过调用导航到您的s Router.Navigate。然后,将其绑定RoutingState到特定于平台的路由视图主机。有关入门指南,请参阅路由文档。
< rxui :ReactiveWindow
xmlns :rxui = “ http://reactiveui.net ”
x :Class = “ ReactiveRouting.MainWindow ”
x :TypeArguments = “ vm:MainViewModel ”
xmlns :vm = “ clr-namespace:ReactiveRouting ”
xmlns = “ http ://schemas.microsoft.com/winfx/2006/xaml/presentation “
xmlns :x = ” http://schemas.microsoft.com/winfx/2006/xaml “>
< rxui :RoutedViewHost
Router = “ {Binding Router} ”
HorizontalContentAlignment = “ Stretch ”
VerticalContentAlignment = “ Stretch ” />
rxui :ReactiveWindow >