我将列出一个列出所有可用插件的列表框.当选择插件时,插件中定义的WPF UI应显示在ContentControl中.我认为的选择包括:
>需要创建一个实现特定接口的UserControl.我认为这将使插件创建变得容易.实现一个界面,你很好.这个方法的问题是如何将UserControl动态加载到ContentControl中.另外,由于我正在使用MVVM设计模式,因此DataTemplate似乎比UserControl更受欢迎.
>允许从插件加载DataTemplate.我相信这将要求插件包含一个名为某种方式的XAML文件.我的应用程序会将DataTemplate读入我的资源字典,如图所示in this question.我已经看到了很多类似的问题,除了它们通常只需要加载一个额外的预定义的程序集来获取DataTemplates.此问题将需要搜索DataTemplates的任意数量的未知程序集.
如果我选择第二个选项,我想我可以像this answer describes.一样选择DataTemplate
解决方法
IBasePlugin.cs
这个简单的界面允许我们为插件创建一个框架.这将只包含非常基础,因为我们将使用MEF导入插件到我们的主应用程序.
public interface IBasePlugin { Workspaceviewmodel viewmodel { get; } ResourceDictionary View{ get; } }
Plugin.cs
下一部分是Plugin.cs文件.它包含我们的插件的所有属性,以及所有必要的参考;例如我们的View&视图模型.
[Export(typeof(IBasePlugin))] public class Plugin : IBasePlugin { [Import] private MyPluginviewmodel _viewmodel { get; set; } private ResourceDictionary _viewDictionary = new ResourceDictionary(); [ImportingConstructor] public Plugin() { // First we need to set up the View components. _viewDictionary.Source = new Uri("/Extension.MyPlugin;component/View.xaml",UriKind.RelativeOrAbsolute); } ....Properties... }
View.xaml
这是一个DataTemplate,其中包含一个对View和viewmodel插件的引用.这就是我们将使用Plugin.cs加载到主应用程序,以便应用程序和WPF将知道如何绑定所有内容.
<DataTemplate DataType="{x:Type vm:MyPluginviewmodel}"> <vw:MyPluginView/>
然后,我们使用MEF加载所有插件,将它们提供给负责处理插件的Workspace viewmodel,并将它们存储在将用于显示所有可用插件的ObservableCollection中.
var plugins = Plugins.OrderBy(p => p.Value.viewmodel.HeaderText); foreach (var app in plugins) { // Take the View from the Plugin and Merge it with,// our Applications Resource Dictionary. Application.Current.Resources.MergedDictionaries.Add(app.Value.View) // THen add the viewmodel of our plugin to our collection of viewmodels. var vm = app.Value.viewmodel; Workspaces.Add(vm); }
一旦Dictinoary和viewmodel都从我们的插件加载到我们的应用程序中,我们可以使用TabControl来显示集合.
<TabControl ItemsSource="{Binding Workspaces}"/>
我也给出了类似的答案here以及一些您可能会感兴趣的其他细节.