调用不同模块的 WPF PRISM 对话框 window

Invoke a WPF PRISM dialog window of different module

我有一个带有区域的 WPF PRISM 应用程序——菜单区域和工作区区域。单击菜单后,相应的 view/form 会在工作区区域内打开。我有不同的模块,如员工、组织、财务等......每个模块都有多个 views/forms.

我需要在单击员工 view/form(模块 - 员工)中的按钮时从财务模块打开一个 view/form 作为对话框 window。

有没有办法在 PRISM 中实现同样的功能?

[编辑1]: 这2个模块是独立的模块。我不希望将 Finance 模块的引用添加到 Employee 模块。再往下,我可能需要从一个或多个财务视图中将员工显示为对话框 window。

当然 - 这里有两种方式供您考虑。

选项 1

Prism 的 documentation 有一节关于 "Making a command globally available" 使用他们的 CompositeCommand class。为此,在两个程序集都可以引用的公共库中创建一个 public 静态 class:

public static class GlobalCommands
{
    public static CompositeCommand ShowFinanceFormCommand = new CompositeCommand();
}

在财务表单视图模型中,您将注册您的实际命令(具有显示表单的所有逻辑):

public FinanceViewModel()
{
    GlobalCommands.ShowFinanceFormCommand.RegisterCommand(this.ShowFinancePopupCommand); 
}

在员工视图模型中,将按钮的 ICommand 绑定到 ShowFinanceFormCommand 复合命令。

public EmployeeViewModel()
{
    this.EmployeeShowFinanceFormCommand = GlobalCommands.ShowFinanceFormCommand;
}

选项 2

如果您需要以松散耦合的方式跨模块广播事件,请使用 Prism 的 EventAggregator class。要实现这一点,请在两者都可以引用的公共程序集中创建一个 ShowFinanceFormEvent。在员工视图模型中,按下按钮时发布一个事件。在财务视图模型中,订阅该事件并做出相应反应。

// This sits in a separate module that both can reference
public class ShowFinanceFormEvent : PubSubEvent<object>
{
}

public class EmployeeViewModel
{
    private readonly IEventAggregator eventAggregator;

    public EmployeeViewModel(IEventAggregator eventAggregator)
    {
        this.ShowFormCommand = new DelegateCommand(RaiseShowFormEvent);
        this.eventAggregator = eventAggregator;
    }

    public ICommand ShowFormCommand { get; }

    private void RaiseShowFormEvent()
    {
        // Notify any listeners that the button has been pressed
        this.eventAggregator.GetEvent<ShowFinanceFormEvent>().Publish(null);
    }
}

public class FinanceViewModel
{
    public FinanceViewModel(IEventAggregator eventAggregator)
    {
        // subscribe to button click events
        eventAggregator.GetEvent<ShowFinanceFormEvent>().Subscribe(this.ShowForm);

        this.ShowFinanceFormRequest = new InteractionRequest<INotification>();
    }

    public InteractionRequest<INotification> ShowFinanceFormRequest { get; }

    private void ShowForm(object src)
    {
        // Logic goes here to show the form... e.g.
        this.ShowFinanceFormRequest.Raise(
            new Notification { Content = "Wow it worked", Title = "Finance form title" });
    }
}

选项 3,也是我认为更好的选项,就是使用 Prism 的导航框架。如果你需要显示一个对话框,那么使用一个对话框服务并简单地将视图键传递给该服务来确定在对话框中显示哪个视图。由于您使用的是唯一键而不是引用,因此您不必知道或关心视图存在的位置。

我在这里的 PluralSight 课程中使用了类似的方法:

https://app.pluralsight.com/library/courses/prism-showing-multiple-shells/table-of-contents

查看对话服务演示。