在 PRISM 中处理 "Popup" Window.xaml

Handling "Popup" Window.xaml in PRISM

我正在使用 MVVM 和 PRISM 7 开发 WPF 应用程序。

在某些地方,我想通过单击按钮打开一个新的 Window.xaml

所以我创建了 Window.xaml 并在单击 button/command 时这样调用它:

private void OnInstrumentFinderCommand()
{
    var instrumentfinder = new InstrumentFinderWindow();
    var result = instrumentfinder.ShowDialog();
    if (result == true)
    {
        // logic here...   
    }
}

效果很好。 InstrumentFinderWindow 打开了,我可以与之互动。

但这打破了我想通过 MVVM 实现的松散耦合。

我知道如何将 PRISM 与 Views 和 Modules 一起使用,但无法弄清楚我必须如何处理 Window 才能获得与上述代码相同的结果,但松耦合resp。不要直接从 ViewModel.

中调用它

有没有办法或者我必须以完全不同的方式处理这个问题?

编辑: 我只是想澄清一下,我问的是一种将 System.Windows.Window 称为 MVVM/PRISM-way 的方法。与 "Yes/No/Cancel" 弹出对话框无关。

调用 PRISM 方式的弹出对话框可以通过 Interaction User Experience.

完成

这种方式描述的很透彻in PRISM documentation and there are bunch of examples how to do it properly in prism samples(25-NotificationRequest, 26-ConfirmationRequest, 27-CustomContent, 28-CustomRequest)。

在您的 ViewModel 中声明 InteractionRequest<T> 属性:

public InteractionRequest<Notification> FindInstrumentRequest { get; }

在命令中提出请求

private void OnInstrumentFinderCommand() {
    FindInstrumentRequest.Raise(
        new Notification(), 
        notification =>
        {
             //the dialog shown, logic here
        });
}

将交互触发器添加到 window 视图

<UserControl ...
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:prism="http://prismlibrary.com/">

    <i:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding FindInstrumentRequest}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <views:InstrumentFinderWindow />
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>
    </i:Interaction.Triggers>

...

</UserControl>

通过InstrumentFinderWindowViewModel实现IInteractionRequestAware接口,调用FinishInteraction完成交互

public partial class InstrumentFinderWindowViewModel: UserControl, IInteractionRequestAware
{
    private void SelectInstrument()
    {
        FinishInteraction?.Invoke();
    }

    public Action FinishInteraction { get; set; }
    public INotification Notification { get; set; }
}

您可以创建 NotificationRequest 的派生类型并使用它在 window 和对话框之间传递数据。

重要补充: 这种交互机制将在 PRISM 的功能版本中被删除。现在正在实施一种处理对话框的新方法:DialogService。它在 PRISM 库的预发布版本中。