我创建了一个“弹出窗口”窗口,根据Prism文档使用PopupWindowAction显示.视图加载得很好,但ViewModel不是.我能找到的所有示例都只是在视图后面的代码中创建了一个简单的ViewModel.我的ViewModel需要由unity构造,以便可以注入依赖项,但是由于视图是在xaml中声明的,所以这是被绕过的:
<prism:InteractionRequestTrigger SourceObject="{Binding CustomViewRequest, Mode=OneWay}">
<prism:PopupWindowAction>
<prism:PopupWindowAction.WindowContent>
<views:CustomView />
</prism:PopupWindowAction.WindowContent>
</prism:PopupWindowAction>
</prism:InteractionRequestTrigger>
我有一个部分解决方法,即在PopupWindowAction.WindowContent中嵌入一个ContentControl(带有一个区域).这是有效的,当我将视图加载到区域时,ViewModel是为我创建的.但是,每次出现窗口时,它都与所有显示中的总桌面空间大小相同.
我在想我可以实现一些代码来设置弹出窗口的起始位置和尺寸,但是我无法访问Window,因为这是在PopupWindowAction中为我创建的.我不想限制底层ContentControl或View的大小,否则用户将无法调整窗口大小.另外,这只是一种解决方法!
那么如何让PopupWindowAction使用依赖注入来加载ViewModel呢?或者,如果这不是直截了当,如何访问Window维度并将它们绑定到与ContentControl中的视图关联的viewmodel?
解决方法:
我遇到了同样的需求,并且能够使用自定义派生的PopupWindowAction,以允许它的WindowContent组合.根据Prism doc Unity doesn’t support the TryResolve extension method,但如果您对Unity更熟悉,可能有另一种方法可以在Unity中使用TryResolve部分.
所以我定义了一个ComposablePopupWindowAction,它添加了一个WindowContentType依赖属性.然后我重写了Invoke方法,使用服务定位器获取WindowContentType的实例(如果已定义).
// a popupWindowAction that allows the DI to compose its view
public class ComposablePopupWindowAction : PopupWindowAction
{
public static readonly DependencyProperty WindowContentTypeProperty =
DependencyProperty.Register(
"WindowContentType",
typeof(Type),
typeof(ComposablePopupWindowAction),
new PropertyMetadata(null),
v => {
Type type = v as Type;
Type frameworkElementType = typeof(FrameworkElement);
// either this is not specified, or if it is then it needs to be a FrameworkElement
return (v == null) || type.IsSubclassOf(frameworkElementType) || (type == frameworkElementType);
}
);
public Type WindowContentType
{
get { return (Type)GetValue(WindowContentTypeProperty); }
set { SetValue(WindowContentTypeProperty, value); }
}
protected override void Invoke(object parameter)
{
ConfigureWindowContent();
base.Invoke(parameter);
}
protected void ConfigureWindowContent()
{
// configure the windowContent if not specified, but a type was
if ((this.WindowContentType != null) && (this.WindowContent == null))
{
// this doesn't appear to be supported in Unity so might need slightly different logic here?
var view = ServiceLocator.Current.TryResolve(this.WindowContentType);
// if can't get thedesired type then base will use the notification
if ((view != null) && (view.GetType() == this.WindowContentType))
{
this.WindowContent = view as FrameworkElement;
}
}
}
}
然后正常执行interactionRequestTrigger,并指定WindowContentType属性的视图类型:
<prism:InteractionRequestTrigger SourceObject="{Binding ConfigurationPopupRequest, Mode=OneWay}">
<inf:ComposablePopupWindowAction IsModal="True" CenterOverAssociatedObject="True" WindowContentType="{x:Type analysis:ConfigurationPopupView}" />
</prism:InteractionRequestTrigger>