代码之家  ›  专栏  ›  技术社区  ›  Rex Logan

带MEF的Winforms

  •  1
  • Rex Logan  · 技术社区  · 17 年前

    我有一个winforms应用程序,它使用不同的选项卡。我希望使用MEF能够添加更多在启动时导入的选项卡。我很难弄清楚该怎么做。

    编辑:

    我使用了主winforms类并将其分条,这样其中只有一个TabControl,我通过一个接口向每个TabPage公开它。然后,我还创建了第二个接口ITab,与MEF一起使用该接口获取tabpage,然后将其添加到主tabcontrol中。要创建一个新的选项卡页面,我只需添加一个新表单,然后向其中添加一个tabcontrol并设计选项卡页面。我将ITab接口添加到新表单中,并添加以下将页面移动到主表单的方法。

    public void MoveTabPages(IForm fm)
    {
       while (this.tabControl1.Controls.Count > 0)
       {
          fm.tab.Controls.Add(this.tabControl1.Controls[0]);
       }
    }
    

    这是完整的代码。

    
    //Form1.cs
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    
    namespace Winforms_Mef
    {
       public interface IForm
       {
          TabControl tab { get; }
       }
    
       public interface ITab
       {
          void MoveTabPages(IForm fm);
       }
    
       public partial class Form1 : Form,IForm
       {
          private CompositionContainer _container;
    
          [Import]
          public IEnumerable Tabs { get; set; }
    
          public TabControl tab
          {
             get { return tabControl1; }
          }
    
          public Form1()
          {
             Compose();
             InitializeComponent();
    
             foreach (ITab tab in Tabs)
             {
                tab.MoveTabPages(this);
             }
    
          }
    
          private void Compose()
          {
             var catalog =new AssemblyCatalog(typeof(ITab).Assembly);
             var batch = new CompositionBatch();
             batch.AddPart(this);
    
             _container =new CompositionContainer(catalog);
             _container.Compose(batch);
          }
       }
    }
    
    
    //Form2.cs
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ComponentModel.Composition;
    
    namespace Winforms_Mef
    {
       [Export(typeof(ITab))]
       public partial class Form2 : Form,ITab
       {
          public Form2()
          {
             InitializeComponent();
          }
    
    
          public void MoveTabPages(IForm fm)
          {
             while (this.tabControl1.Controls.Count > 0)
             {
                fm.tab.Controls.Add(this.tabControl1.Controls[0]);
             }
          }
       }
    }
    
    
    
    2 回复  |  直到 17 年前
        1
  •  2
  •   TheCodeJunkie    17 年前

    在继续之前,我认为您的撰写方法需要清理。为什么要将容器和目录添加到批处理中?

    batch.AddExportedObject(_container);
    batch.AddExportedObject(catalog);
    

    AddExportedObject 用于将预先存在的对象实例添加为导出,尝试使用容器和目录作为导出没有多大意义

    privat void Compose()
    {
        var catalog =
            new AssemblyCatalog(typeof(ITab).Assembly);
    
        var batch =
            new CompositionBatch();
        batch.AddPart(this);
    
        var container =
            new CompositionContainer(catalog);
        container.Compose(batch);
    }
    
        2
  •  0
  •   Rex Logan    17 年前

    这是一个通用版本,允许您使用Mef将winforms表单与其他表单交换。有一个使用Mef公开的IForm接口,它有一个名为public void MoveForm(Form-Form)的方法,它将新表单复制到旧表单上。

    这是代码。

    
    
    //// Form1 default form
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    
    namespace Winforms_Mef
    {
       public interface IForm
       {
          void MoveForm(Form form);
       }
    
       public partial class Form1 : Form 
       {
          private CompositionContainer _container;
    
          [Import]
          public IEnumerable Forms { get; set; }
    
          public Form1()
          {
             Compose();
             InitializeComponent();
    
             foreach (IForm form in Forms)
             {
                this.SuspendLayout();
                this.Controls.Clear(); // wipe out the current version of the form
                this.ResumeLayout(false);
                form.MoveForm(this);
             }
    
          }
    
          private void Compose()
          {
             var catalog = new AssemblyCatalog(typeof(IForm).Assembly);
             var batch = new CompositionBatch();
             batch.AddPart(this);
    
             _container = new CompositionContainer(catalog);
             _container.Compose(batch);
          }
       }
    }
    
    //// Form 2 uses Mef to replace Form1
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ComponentModel.Composition;
    
    namespace Winforms_Mef
    {
       [Export(typeof(IForm))]
       public partial class Form2 : Form,IForm
       {
          public Form2()
          {
             InitializeComponent();
          }
    
    
          public void MoveForm(Form form)
          {
             this.SuspendLayout();
             form.SuspendLayout();
    
             form.AutoScaleDimensions = this.AutoScaleDimensions;
             form.AutoScaleMode=this.AutoScaleMode;
             form.ClientSize=this.ClientSize;
             form.Name=this.Name;
             form.Text=this.Text;
             while (this.Controls.Count > 0)
             {
                form.Controls.Add(this.Controls[0]);
             }
    
             this.ResumeLayout(false);
             form.ResumeLayout(false);
          }
       }
    }
    
    
    
    
    推荐文章