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 调用并完全删除显式构造函数。
看了部分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 调用并完全删除显式构造函数。