【问题标题】:WPf, MEF Architecture designWPf, MEF 架构设计
【发布时间】:2013-07-24 04:40:55
【问题描述】:

我在设计可扩展程序的架构时遇到了一些问题。

我正在使用 MEF、MMVM Light Toolkit 和 AvalonDock。

第一个问题是如何使用 MEF 从另一个程序集中导入一些 ViewModel 的显示视图。 为了解决这个问题,我导出了ResourceDictionary,我在其中为在这个程序集中声明的视图定义了DataTemplate

Dictionary:

<ResourceDictionary 
  ...>
  <DataTemplate DataType="viewmodels:MyViewModel">
    <views:MyViewForViewModel/>
  </DataTemplate>
</ResourceDictionary>

MainWindow 的构造函数中,我正在导入所有ResourceDictionaries 并将它们与MainWidow.ResourceDictionary 合并。 好吗?也可以指定ResourceDictionary 的“范围”,而不是将其导入到MainWindow,而是导入到Application,例如。

第二个问题是ICommandsCommandBindings。 要填充Menu,我正在导出“MenuItems”,我在其中定义ICommandText 和其他内容,但我不知道如何导出CommandBinding,我应该使用RelayCommand 来处理以下情况我无法创建CommandBinding

第三个问题是对话框。 我找到了很棒的文章 Showing Dialogs When Using the MVVM Pattern 并轻松地将其改编为 MEF。但是,例如,我有一个没有任何视图的IDatabaseServiceWorkspace,主 ViewModel,存储IDatabaseService 的实例并创建菜单项:Connect to Database。使用 IDialogService 工作区打开一些导入的IConnectToDbDialog 所以Workspace 对此一无所知。当对话框关闭时,SqlConnectionString 应该被传递给IDatabaseService。 那么谁必须通过这个SqlConnectionStringIConnectToDbDialogWorkspace

第四个问题是如何与IDatabaseService正确通信。 例如。在某些视图中,我有Button:'在数据库中创建项目'。当单击按钮时,我应该如何调用IDatabaseService 方法CreateItem(ElementType elementType)? 问题是,有很多按钮在数据库中创建 Items 和不同的 ElementType,所以,我认为,使用参数创建一些 ICommand 并为此命令创建一个处理程序是正确的,它将调用一些IDatabaseService 中的方法。但我不知道怎么做。 另一种解决方案是从ViewModelIDatabaseService 发送消息以创建项目。 哪个更好?

【问题讨论】:

    标签: wpf mvvm architecture mef


    【解决方案1】:

    试着回答你的问题。

    1. 很好。您可以在 XAML 或代码后面合并,但我更喜欢 XAML。可以放在MainWindow.Xaml上,在主窗口范围内,也可以放在App.Xaml上,在应用范围内。

    2. 我之前没有导出视图。在我看来,如果您将 CommandBindings 放在 Menu 下,如果事件处理程序在导入的环境范围内,则何时导出然后导入都没有关系。

    3. 视情况而定。从理论上讲,您可以将服务调用放在所有者的视图模型或对话框的视图模型中。例如,如果您的对话框有一个创建/提交按钮,并且您希望对话框在提交成功之前保持活动状态,则将其放入对话框的视图模型中,以便在处理异常时可以保持打开状态。如果你不需要对话框保持打开,那么你可以在对话框关闭后将逻辑放在所有者的视图模型中。

    4. 命令更好。考虑到视图模型从 IoC 容器中获取 IDatabaseService 对象,您可能有一个接受 ElementType 参数的 ICommand 属性,或者一个参数可以映射到 ElementType。在执行方法中,您调用 CreateItem 直接或从映射器传递参数。在您的 XAML 上,您将 type 放入命令绑定中。有意义吗?

    希望对你有帮助。

    【讨论】:

    • 谢谢。 3和4的答案很清楚,但是我对1和2有一些疑问,可能是我的错。 1. 我也更喜欢 XAML,但在我的任务中,我只能访问主程序集源代码和通用接口,我无法访问视图或菜单或其他块源代码,所以除了我的之外,我看不到任何其他解决方案。
    • 2.我不知道该怎么做。我只能访问IMenuIMenuItem 接口和MenuItem 类。在某些程序集中,我在ResourceDictionary 中导出class Menu : IMenuDataTemplate 以在shell 中显示菜单。并添加一些IMenuItem 我正在导出class MenuItem : IMenuItem 或在从IoC 获得的IMenu 中调用方法AddMenuItem(IMenuItem),所以我无法在Menu 下定义CommandBindings。我只能在代码中做到这一点,但这是有问题的,但可能。
    • 在共享程序集中 public class WorkspaceCommands { public static RoutedUICommand ConnectToDB{ get { return connectToDB; } } static readonly RoutedUICommand connectToDB = new RoutedUICommand("连接到数据库", "ConnectToDatabase", typeof(WorkspaceCommands));在MainWindow 或其他地方我必须创建CommandBinding 来处理它。
    • 我在这里没有看到命令绑定与您的菜单有任何关系。您的 RoutedCommand 在共享程序集上定义,您的命令绑定在 XAML 上定义。
    • 你能解释一下吗,我不明白。
    猜你喜欢
    • 2016-08-23
    • 2010-09-28
    • 2011-11-18
    • 2012-09-17
    • 2016-06-22
    • 2020-07-24
    • 2012-08-25
    • 2011-05-25
    • 1970-01-01
    相关资源
    最近更新 更多