【问题标题】:How to use ReactiveUI inside a PRISM module如何在 PRISM 模块中使用 ReactiveUI
【发布时间】:2015-10-05 19:42:13
【问题描述】:

我们有一个现有的 WPF 应用程序,它使用 PRISM (6.x) 和 Unity (3.5.x) 进行 DI。我们将为这个应用程序添加更多功能,并希望开始将 ReactiveUI 用于我们需要实现的任何新模块。

我们希望尽量减少学习曲线,并继续将 Unity 和 DI 用于我们的 ViewModel;但是,ReactiveUI 使用Splat 作为查看位置,到目前为止,无论我尝试了什么,我都无法让我的 ReactiveUI 模块实际显示在主应用程序的 PRISM 区域中。

我真正找到的唯一一篇文章是这篇帖子 Issues with IMutableDependencyResolver and Structuremap in ReactiveUI,其中有人正在编写自己的集成。

所以给定一些 ViewModel:

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

及其对应的View:

<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&lt;T&gt;接口背后的视图代码:

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">

我也尝试过在模块的初始化中初始化 Splat:

    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 的框架结合使用的好处的人。

【问题讨论】:

    标签: c# wpf unity-container prism reactiveui


    【解决方案1】:

    Prism 和 RxUI 以及视图绑定的不同语义。

    Prism 尝试为给定视图解析 VM 类型,而 RxUI 则相反,为当前 VM 解析视图。

    您的实现(几乎)工作:

    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 RoutedViewHostViewModelViewHost 并将其中一个绑定到该区域中。然后 RxUI 视图解析将自动启动,并根据控件上设置的当前 VM 刷新内部视图。这是您需要注册视图的时候,就像您所做的那样:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 2021-03-15
      • 1970-01-01
      • 2012-07-29
      • 2018-09-26
      • 1970-01-01
      相关资源
      最近更新 更多