Prism5 PopupWindowAction 和注入

Prism5 PopupWindowAction and injection

看了部分InteractivityQuickstart官方例子

<prism:InteractionRequestTrigger SourceObject="{Binding ItemSelectionRequest, Mode=OneWay}">
        <prism:PopupWindowAction>
            <prism:PopupWindowAction.WindowContent>
                <views:ItemSelectionView />
            </prism:PopupWindowAction.WindowContent>
        </prism:PopupWindowAction>
    </prism:InteractionRequestTrigger>

因此,ItemSelectionRequest 调用了少参数构造函数

public ItemSelectionView()
{
    this.DataContext = new ItemSelectionViewModel();
    InitializeComponent();
}

在 ItemSelectionView 的代码隐藏中。

问题: 1) 如何在没有 "new" 的情况下设置 DataContext,因为

public ItemSelectionView(ItemSelectionViewModel model)

[Dependency]
public ItemSelectionViewModel ViewModel
{
    set { this.DataContext = value; }
}

不起作用。 我需要在 ViewModel 中获得一些服务 => 我需要这样调用

public ItemSelectionViewModel(IEventAggregator eventAggregator)
{
    _eventAggregator=eventAggregator;
}

如果您的 Popup ViewModel 需要服务,您可以使用 ServiceLocator 获取它。

public ItemSelectionView()
{
    InitializeComponent();
    DataContext = ServiceLocator.Current.GetInstance<ItemSelectionViewModel>();
}

与其像 Brian Lagunas 建议的那样使用 ServiceLocator 设置 ViewModel,为什么不使用 ViewModel 的无参数构造函数,直接在视图中设置 ViewModel class(XAML 或代码隐藏),并在 ViewModel 本身中使用 ServiceLocator 来获取您的 ViewModel 需要的服务(或其接口)?我建议这样做有两个原因:

  • 在弹出窗口的视图的构造函数中使用 ServiceLocator 会在设计时在 "prism:PopupWindowAction.WindowContent" 部分中出现 "ServiceLocationProvider must be set" 错误。 (尽管它在运行时运行良好。)
  • 您已经被迫陷入必须以某种方式绕过依赖注入的境地,所以为什么不简化代码,特别是如果您无论如何只需要访问一项服务。

所以你可以这样做:

public ItemSelectionViewModel()
{
    _eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
}

如果您只需要使用一次 IEventAggregator 对象,则没有理由将它分配给一个字段。只需在需要获取事件聚合器的地方使用 ServiceLocator 调用并完全删除显式构造函数。