8

我在尝试在 shell 窗口中为各种视图管理 VM 状态、为大量编辑对话(模态或非模态)以及窗口本身的状态之间切换时经历了太多痛苦。

现在我想用一个shell窗口重做,希望只有一个对话窗口,那么我的windows和Vms的耦合要小得多,我可以借用shell的VM管理模式来管理对话。

我看到了很多直接管理弹出窗口和不太通用的非模态的指导,但是是否有任何既定的模式或指导可以只使用一个对话来托管各种虚拟机?更好的是,Prism 中是否已经提供任何此类功能?

我想真正坚持 DRY 原则,并且视图和 VM 中的继承增加了我无法承受的复杂性,这在本应是快速的第一次迭代原型上是无法承受的。

4

2 回答 2

5

好吧,我不知道任何开箱即用的解决方案,但是创建这样一个可重用的对话框实现并不难。实际上,几年前我实现了类似的东西。好吧,那是另一份工作,所以我再也无法访问代码了。此外,我无法记住所有细节,但我可以尝试为您提供这种实现的基本概念。

您可以创建一个DialogVm提供通用对话框功能的 .

首先,表示层中的对话框需要什么?通常,三个按钮,如...

  • 应用取消关闭(修改对话框)
  • 确定取消或是和问题对话框)
  • 好的(如果是消息框)

如您所见,您需要三个命令(ICommand doc)。实际上,我已经创建了一个DelegateCommand实现(基于this)。ICommand.CanExecute确定绑定按钮是禁用还是启用。如果命令为空,则应隐藏该按钮。

(如果您使用的是正确的布局控件,则按钮的位置会正确调整,如果未显示按钮。)

为了提供对上述四种以上场景的支持,我在 中添加了一个CommandTitle属性DelegateCommand,以便按钮的内容来自那里。

接下来你需要一个Title属性作为对话框的标题。所以将这个添加到DialogVm.

如果您希望能够Window通过执行命令来关闭对话框(只有必要,如果它是 的子级),您可以遵循这种方法。当然,我已经使用了我在那里描述的版本。但其他人也看起来很有希望。

最后一个打开点是一个属性,表示不同的对话框内容。如果我没记错的话,我使用了一小组视图模型和相应DataTemplates的(当然还有一个TemplateSelector,它根据 VM 类型提供正确的模板)。当然,您还需要ContentPresenter对话框中的控件,该控件DataTemplate显示TemplateSelector.

如果您只有几种不同的对话框类型(例如问题框、消息框...),这是唯一的下站点,它只是一个好方法

使用非常简单。DialogVm简单地说,用所需的ICommand逻辑初始化一个实例, DialogContentVm(无论如何你想调用它),将它传递给DialogWindow(也许,你想使用一些不同的东西,例如浮出控件)并将其呈现给用户。

好吧,我希望它有所帮助。如果您需要更多信息或任何帮助,请告诉我。

于 2017-01-04T14:27:39.617 回答
3

这实际上很简单,但有一些复杂性。首先,您需要创建一个自定义对话服务。这项服务可以根据您的喜好简单或复杂。该服务将做的主要事情是显示一个对话框,该对话框被视为它自己的外壳。这意味着对话框将是相同的,但对话框中的内容会根据您在调用它时传递给它的信息而有所不同。所以这意味着一个带有自己区域的自定义对话框。为了处理在对话框外壳中使用不同的视图,我将使用导航服务。

您的对话框可能如下所示:

public interface IDialogService
{
    void ShowDialog(string uri);
}

public class DialogService : IDialogService
{
    private readonly IUnityContainer _container;
    private readonly IRegionManager _regionManager;

    public DialogService(IUnityContainer container, IRegionManager regionManager)
    {
        _container = container;
        _regionManager = regionManager;
    }

    public void ShowDialog(string uri)
    {
        var dialog = _container.Resolve<DialogShell>();
        //use a scoped region just in case you can have multiple instances
        var scopedRegion = _regionManager.CreateRegionManager();
        //set the region manager of the dialog to the scoped region
        RegionManager.SetRegionManager(dialog, scopedRegion);
        //navigate to show the desired view in the dialog
        scopedRegion.RequestNavigate(KnownRegionNames.ContentRegion, uri);
        //show the dialog
        dialog.Show();
    }
}

您可以修改此方法以完全满足您的需求,但您明白了。

编辑:我还想提一下,您甚至可以通过允许您的对话框在其中拥有自己的单独导航并且对显示的每个实例都是唯一的来对此感到疯狂。如果您有兴趣,我有一个 Pluralsight 课程,它会展示如何做到这一点。https://www.pluralsight.com/courses/prism-showing-multiple-shells

于 2017-01-11T19:09:20.100 回答