我将列出一个列出所有可用插件的列表框.当选择插件时,插件中定义的WPF UI应显示在ContentControl中.我认为的选择包括:
>需要创建一个实现特定接口的UserControl.我认为这将使插件创建变得容易.实现一个界面,你很好.这个方法的问题是如何将UserControl动态加载到ContentControl中.另外,由于我正在使用MVVM设计模式,因此DataTemplate似乎比UserControl更受欢迎.
>允许从插件加载DataTemplate.我相信这将要求插件包含一个名为某种方式的XAML文件.我的应用程序会将DataTemplate读入我的资源字典,如图所示in this question.我已经看到了很多类似的问题,除了它们通常只需要加载一个额外的预定义的程序集来获取DataTemplates.此问题将需要搜索DataTemplates的任意数量的未知程序集.
如果我选择第二个选项,我想我可以像this answer describes.一样选择DataTemplate
解决方法@H_502_13@
我做了类似于DataTemplates提到的类似的东西.我使用
MEF加载插件,然后在启动时加载了一个引用viewmodel和View的Dictionary.该插件使用3个主要组件构建.
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以及一些您可能会感兴趣的其他细节.
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以及一些您可能会感兴趣的其他细节.