2015-10-05 128 views
1

我們有一個現有的WPF應用程序,使用PRISM(6.x)和Unity(3.5.x)進行DI。我們將爲此應用程序添加更多功能,並希望開始使用ReactiveUI來處理我們需要實現的任何新模塊。如何在PRISM模塊中使用ReactiveUI

我們希望儘量減少學習曲線,並繼續爲ViewModel使用Unity和DI;然而,ReactiveUI使用Splat來查看位置,到目前爲止我無法讓我的ReactiveUI模塊實際顯示在我們的主應用程序中的PRISM區域,無論我嘗試了什麼。

我真的找到的唯一的文章是這篇文章Issues with IMutableDependencyResolver and Structuremap in ReactiveUI有人在寫自己的整合。

所以給出了一些視圖模型:

public class HelloWorldViewModel : ReactiveObject 
{ 
    string title = "Hello ReactiveUI"; 
    public string Title 
    { 
     get { return title; } 
     set { this.RaiseAndSetIfChanged(ref title, value); } 
    } 
} 

及其相應的視圖:

<UserControl x:Class="PBI.ObjectMover.ReactSample.Views.HelloWorldView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"> 
    <Grid> 
    <TextBlock Text="{Binding Title}" Foreground="Green" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Calibri" FontSize="24" FontWeight="Bold"></TextBlock>    
    </Grid> 
</UserControl> 

和視圖的背後實現IViewFor<T>接口代碼:

public partial class HelloWorldView : UserControl, IViewFor<HelloWorldViewModel> 
{ 
    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)); 
    } 
} 

我曾嘗試加入棱鏡定位到視圖的XAML:

<UserControl x:Class="PBI.ObjectMover.ReactSample.Views.HelloWorldView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:prism="http://prismlibrary.com/" 
     prism:ViewModelLocator.AutoWireViewModel="True"> 

我也曾嘗試在模塊的初始化初始化啪:

public void Initialize() 
    { 
     /* Register types */ 
     Locator.CurrentMutable.InitializeSplat(); 
     Locator.CurrentMutable.InitializeReactiveUI(); 
     Locator.CurrentMutable.Register(() => new HelloWorldView(), typeof(IViewFor<HelloWorldViewModel>)); 

     /* Register views */ 
     this.RegionManager.RegisterViewWithRegion("RightRegion", typeof(HelloWorldView)); 
    } 

到目前爲止,一切都沒有工作,但我懷疑我們是唯一能看到使用PRISM的模塊化體系結構和ReactiveUI框架的好處的人。

回答

2

棱鏡和RxUI和視圖綁定上的不同語義。

Prism嘗試爲給定視圖解析VM類型,而RxUI以相反方式解決此問題併爲當前VM解析View。

你的實現是(幾乎)工作:

this.RegionManager.RegisterViewWithRegion("RightRegion", typeof(HelloWorldView)); 

這足以顯示視圖,如果添加AutoWireViewModel=True,棱鏡將創建一個虛擬機實例,並將其設置到您的視圖DataContext

要注意的是這行:

this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext); 

試圖將ViewModel屬性綁定到同一DataContext,並愉快地與空這樣做,覆蓋創建的實例/通過棱鏡(這裏是你的問題,我相信)設置。

簡單地刪除這個綁定的作品,但總體來看,它似乎並不是一個混合Prism和RxUI的好方法。

也許您可以看看RxUI RoutedViewHostViewModelViewHost,並將其中一個綁定到區域中。然後,RxUI視圖解析將自動啓動,並根據控件上設置的當前VM來刷新內部視圖。這是當你需要註冊你的意見,就像你做的那樣:

Locator.CurrentMutable.Register(() => new HelloWorldView(), typeof(IViewFor<HelloWorldViewModel>)); 
相關問題