如何在PRISM模块中使用ReactiveUI
我们有一个现有的WPF应用程序,它使用PRISM(6.x)和Unity(3.5.x)进行DI。 我们将为此应用程序添加更多function,并希望开始将ReactiveUI用于我们需要实现的任何新模块。
我们希望尽量减少学习曲线并继续为ViewModels使用Unity和DI; 但是,ReactiveUI使用Splat for View位置,到目前为止,我无法让我的ReactiveUI模块实际显示在我们的主应用程序中的PRISM区域,无论我尝试过什么。
我真正找到的唯一一篇文章就是这篇文章在ReactiveUI中的IMutableDependencyResolver和Structuremap问题,其中有人正在编写自己的集成。
所以给出了一些ViewModel:
public class HelloWorldViewModel : ReactiveObject { string title = "Hello ReactiveUI"; public string Title { get { return title; } set { this.RaiseAndSetIfChanged(ref title, value); } } }
及其相应的观点:
以及实现IViewFor
接口背后的视图代码:
public partial class HelloWorldView : UserControl, IViewFor { public HelloWorldView() { InitializeComponent(); this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext); } public HelloWorldViewModel ViewModel { get { return (HelloWorldViewModel)GetValue(ViewModelProperty); } set { SetValue(ViewModelProperty, value); } } public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register("ViewModel", typeof(HelloWorldViewModel), typeof(HelloWorldView), new PropertyMetadata(null)); object IViewFor.ViewModel { get; set; } }
在IModule初始化中需要什么才能将ReactiveUI ViewModel和View连接起来?
public class ReactSampleModule : IModule { private readonly IRegionManager RegionManager; public ReactSampleModule(IUnityContainer container, IRegionManager regionManager) { this.RegionManager = regionManager; } public void Initialize() { /* What do I need here to initialize ReactiveUI or Unity? */ /* Register views */ this.RegionManager.RegisterViewWithRegion("RightRegion", typeof(HelloWorldView)); } }
我尝试将棱镜定位器添加到View的XAML中:
我也尝试在模块的初始化中初始化Splat:
public void Initialize() { /* Register types */ Locator.CurrentMutable.InitializeSplat(); Locator.CurrentMutable.InitializeReactiveUI(); Locator.CurrentMutable.Register(() => new HelloWorldView(), typeof(IViewFor)); /* Register views */ this.RegionManager.RegisterViewWithRegion("RightRegion", typeof(HelloWorldView)); }
到目前为止,没有任何工作,但我怀疑我们是唯一看到使用PRISM的模块化架构和ReactiveUI框架的好处的人。
Prism和RxUI以及视图绑定的不同语义。
Prism尝试为给定视图解析VM类型,而RxUI则以相反的方式执行此操作并解析当前VM的View。
您的实施(几乎)正在运行:
this.RegionManager.RegisterViewWithRegion("RightRegion", typeof(HelloWorldView));
这足以显示视图,如果添加AutoWireViewModel=True
,Prism将创建一个VM实例并将其设置为您的视图DataContext
。
请注意这一行:
this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext);
尝试将ViewModel
属性绑定到同一个DataContext
,并且很乐意使用null,覆盖Prism创建/设置的实例(我相信这是你的问题)。
简单地删除这个绑定工作,但总体来说它似乎不是混合Prism和RxUI的好方法。
也许您可以查看RxUI RoutedViewHost
和ViewModelViewHost
并将其中一个绑定到该区域。 然后RxUI视图解析将自动启动,并根据控件上设置的当前VM刷新内部视图。 这是您需要注册您的观点,就像您一样:
Locator.CurrentMutable.Register(() => new HelloWorldView(), typeof(IViewFor));