Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将数据从主机绑定到插件_C#_Wpf_Mvvm_Data Binding_Mef - Fatal编程技术网

C# 如何将数据从主机绑定到插件

C# 如何将数据从主机绑定到插件,c#,wpf,mvvm,data-binding,mef,C#,Wpf,Mvvm,Data Binding,Mef,如何使用MEF将数据从主机绑定到插件 所以问题是: 我使用MVVM,所以我有我的模型、视图模型和视图。 我想使用MEF来扩展我的应用程序。 我想在MainViewModel中存储所有数据,这样每个插件都可以处理实际数据。 该插件是一个用户控件,它将在MainViewModel中显示为ContentControl。 到目前为止,我所拥有的: 主视图模型 模型 从MainViewModel到视图的数据绑定。 从文件夹X导入插件 我需要的是: -插件需要将数据从MainViewModel绑定到插件UI

如何使用MEF将数据从主机绑定到插件

所以问题是:

我使用MVVM,所以我有我的模型、视图模型和视图。 我想使用MEF来扩展我的应用程序。 我想在MainViewModel中存储所有数据,这样每个插件都可以处理实际数据。 该插件是一个用户控件,它将在MainViewModel中显示为ContentControl。 到目前为止,我所拥有的:

主视图模型 模型 从MainViewModel到视图的数据绑定。 从文件夹X导入插件 我需要的是: -插件需要将数据从MainViewModel绑定到插件UI。 -更改插件UI中的属性必须更新MainViewModel中的数据,并从所有其他插件更新UI

插件接口:

MainViewModel:它的一部分

private MyModel myfirstmodel; 
private DirectoryCatalog catalog;
private CompositionContainer container;

[ImportMany] 
IEnumerable<Lazy<IPlugin, IPluginData>> Plugins;

public MainWindowViewModel()
{
    string pluginPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    pluginPath = Path.Combine(pluginPath, "plugins");
    if (!Directory.Exists(pluginPath))
    Directory.CreateDirectory(pluginPath);
    catalog = new DirectoryCatalog(pluginPath, "*.dll");
    container = new CompositionContainer(catalog);

    try
    {
        this.container.ComposeParts(this);
    }
    catch (CompositionException compositionException)
    {
        Console.WriteLine(compositionException.ToString());
    }
}
插件

我尝试使用INotifyPropertyChanged,但没有成功

有没有人有一个非常好的教程,或者可以告诉我如何做到这一点? 我将非常感谢如何而不仅仅是使用InotifyProperty更改


这可能吗?

对于使用ModelView交换数据,您需要一个表示主机的接口。您还需要一个容器或方法来插入表示插件的可视控件

 interface IPluginHost 
 {
      MyModelView ModelView {get;}
      MyMainWindow View {get;}
 }

 interface IPlugin
 {
    void Register(IPluginHost host);
    void Unregister();
 }
合成后,您向主机注册插件,这将使它们能够访问模型视图:

this.container.ComposeParts(this);
foreach(var plugin in Plugins)
{
     plugin.Value.Register(this);
}
我需要:-插件需要绑定来自 将MainViewModel添加到插件UI

如果插件可以执行所有必要的绑定,那么它可以通过它的Register方法访问MainViewModel。以下是许多方法之一:

 public partial class MyFirstPlugin : UserControl, IPlugin
 {
      ...

     void Register(IPluginHost host)
     {
          _host = host;

           // Attach main model view as data context
           this.DataContext = host.ModelView; 

           // Add control to the host's container
           var mainWindow = host.View;

           mainWindow.AddPluginControl((UserControl)this);
     }

     void Unregister()
     {
          if (_host == null)
          { 
              return;
          }

          this.DataContext = null;
          _host.View.RemovePluginControl(this);
          _host = null;
     }

     IPluginHost _host;

 }

AddPluginControl、RemovePluginControl是将插件的可视元素插入容器中的公共方法。

我个人认为你这样做是错误的,MEF是专门设计用于进行此类管道的,因此你不必这样做

在适当的MVVM应用程序中,视图通常通过数据模板创建,即使您不这样做,也通常需要导入其他全局数据,如画笔和行为等。如果您确实使用了您真正应该使用的模板,则不需要显式导出控件;通过模板简单地引用它们也会导致导入它们


您可以通过进口商的另一个通行证在实践中实现这一点。为每个插件提供一个定制的ResourceDictionary,并将所有全局数据/模板/UI资源等放在其中,因此它实际上是插件的App.xaml版本。诀窍是,然后给这些ResourceDictionary它们自己的代码隐藏文件,并用导出来修饰这些类。然后,主应用程序所要做的就是导入ResourceDictionary类型的所有类,或者最好是一个派生类或接口,该派生类或接口返回字典并将每个类添加到application.Current.Resources.MergedDictionaries。从这一点上讲,插件的开发与DLL项目中的插件开发几乎相同,而您正以通常的方式进行静态链接。

。。我没有得到注册的那部分。。“Register”方法来自何处?它是什么?如果能找到解决这个问题的线索就好了cRegister是我添加到IPlugin接口声明中的一个方法。我在答案中添加了一个示例。好的。我现在通过插件注册得到了这个。但是我在哪里使用IPluginHost接口呢?我有一个模型视图,它在IPluginHost中使用,并组成所有插件。但是,当我将IPluginHost添加到ModelView时,我必须在MyModelView中设置IPluginHost.MyModelView。。这让我很困惑,你能给我举个简单的例子说明怎么做吗?以前从未使用过ResourceDirectories..:cI发现了6年前我自己最初学会的SO帖子,它是。你只需要记住初始化组件;在构造函数中,否则导入字典时字典将显示为空。谢谢。我试试看我想将UserControl添加到我的应用程序中。此UserControl将添加到总体视图中,并绑定视图中的数据。当主机中的数据更改时,usercontrol也必须更改。我该怎么做?@bene_rawr你可能不得不问第二个问题,关于你的具体情况,有更具体的细节,因为有很多不同的方式。一般来说,您可以将ContentControl与DataTemplate一起使用,也可以将样式与数据触发器一起使用。
 interface IPluginHost 
 {
      MyModelView ModelView {get;}
      MyMainWindow View {get;}
 }

 interface IPlugin
 {
    void Register(IPluginHost host);
    void Unregister();
 }
this.container.ComposeParts(this);
foreach(var plugin in Plugins)
{
     plugin.Value.Register(this);
}
 public partial class MyFirstPlugin : UserControl, IPlugin
 {
      ...

     void Register(IPluginHost host)
     {
          _host = host;

           // Attach main model view as data context
           this.DataContext = host.ModelView; 

           // Add control to the host's container
           var mainWindow = host.View;

           mainWindow.AddPluginControl((UserControl)this);
     }

     void Unregister()
     {
          if (_host == null)
          { 
              return;
          }

          this.DataContext = null;
          _host.View.RemovePluginControl(this);
          _host = null;
     }

     IPluginHost _host;

 }