如何在 MVVM 之后为 WPF 构建通用/可重用模式对话框 [英] How to build a generic/re-usable modal dialog for WPF following MVVM

查看:22
本文介绍了如何在 MVVM 之后为 WPF 构建通用/可重用模式对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个通用/可重复使用的模式对话框,我可以在我们的 WPF (MVVM) - WCF LOB 应用程序中使用它.

I would like to build a generic/re-usable modal dialog that I can use in our WPF (MVVM) - WCF LOB application.

我有一个希望使用对话框显示的视图和关联的视图模型.视图和视图模型之间的绑定是使用以类型为目标的 DataTemplates 完成的.

I have a Views and associated ViewModels that I would like to display using dialogs. Bindings between Views and ViewModels are done using Type-targeted DataTemplates.

以下是我能够起草的一些要求:

Here are some requirements that I have been able to draft:

  • 我更喜欢它基于 Window,而不是使用像模态对话框一样的 Adorners 和控件.
  • 它应该从内容中获取其最小尺寸.
  • 它应该以所有者窗口为中心.
  • 窗口不得显示最小化"和最大化"按钮.
  • 它应该从内容中获得它的标题.

最好的方法是什么?

推荐答案

我正在回答我自己的问题,以帮助其他人找到我在一个地方难以找到的所有答案.以上看似简单的问题,实际上提出了多个我希望在下面充分回答的问题.

I'm answering my own question to help others find all answers I struggled to find in one place. What above seems like a straight forward problem, actually presents multiple problems that I hope to answer sufficiently below.

来了.

用作通用对话框的 WPF 窗口可能如下所示:

Your WPF window that will serve as the generic dialog can look something like this:

<Window x:Class="Example.ModalDialogView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ex="clr-namespace:Example"
        Title="{Binding Path=mDialogWindowTitle}" 
        ShowInTaskbar="False" 
        WindowStartupLocation="CenterOwner"
        WindowStyle="SingleBorderWindow"
        SizeToContent="WidthAndHeight"
        ex:WindowCustomizer.CanMaximize="False"
        ex:WindowCustomizer.CanMinimize="False"
        >
    <DockPanel Margin="3">
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" FlowDirection="RightToLeft">
            <Button Content="Cancel" IsCancel="True" Margin="3"/>
            <Button Content="OK" IsDefault="True" Margin="3" Click="Button_Click" />
        </StackPanel>
        <ContentPresenter Name="WindowContent" Content="{Binding}"/>
    </DockPanel>
</Window>

按照 MVVM,显示对话的正确方法是通过中介.要使用调解器,您通常还需要一些服务定位器.有关调解员的具体细节,请查看这里.

Following MVVM, the right way to show a dialog is through a mediator. To use a mediator, you typically require some service locator as well. For mediator specific details, look here.

我确定的解决方案涉及实现一个 IDialogService 接口,该接口通过一个简单的静态 ServiceLocator 解决.这篇优秀的 codeproject 文章详细介绍了这一点.注意 这个 文章论坛中的消息.该方案还解决了通过 ViewModel 实例发现所有者窗口的问题.

The solution I settled on involved implementing an IDialogService interface that is resolved through a simple static ServiceLocator. This excellent codeproject article has the details on that. Take note of this message in the article forum. This solution also solves the problem of discovering the owner window via the ViewModel instance.

使用这个接口,你可以调用IDialogService.ShowDialog(ownerViewModel, dialogViewModel).现在,我从所有者 ViewModel 调用它,这意味着我的 ViewModel 之间有硬引用.如果您使用聚合事件,您可能会从指挥那里调用它.

Using this interface, you can call IDialogService.ShowDialog(ownerViewModel, dialogViewModel). For now, I'm calling this from the owner ViewModel, meaning I have hard references between my ViewModels. If you use aggregated events, you will probably call this from a conductor.

设置最终将在对话框中显示的视图的最小尺寸不会自动设置对话框的最小尺寸.此外,由于对话框中的逻辑树包含 ViewModel,因此您不能只绑定到 WindowContent 元素的属性.这个问题在我的解决方案中有答案.

Setting the minimum size on the View that will eventually be displayed in the dialog doesn't automatically set the minimum size of the dialog. Also, since the logical tree in the dialog contains the ViewModel, you can't just bind to the WindowContent element's properties. This question has an answer with my solution.

我上面提到的答案还包括以所有者为中心的窗口.

The answer I mention above also includes code that centers the window on the owner.

最后,禁用最小化和最大化按钮是 WPF 本身无法做到的.恕我直言,最优雅的解决方案是使用 这个.

Finally, disabling the minimize and maximize buttons is something WPF can't natively do. The most elegant solution IMHO is using this.

这篇关于如何在 MVVM 之后为 WPF 构建通用/可重用模式对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆