1

I have a winforms App that uses different tabs. I would like to use MEF to be able to add more tabs that are imported at startup. I am having a hard time figuring out how to go about doing this.

Edit: Here is what I did.

I took the main winforms class and striped it down so that there is only a TabControl in it which I expose to each each TabPage through an interface. I then also create a second interface ITab which I use with MEF to get the tabpage and then add it to to the main tabcontrol. To create a new tab page I then just add a new form and then add a tabcontrol to it and design the tab pages. I add the ITab interface to the new form and add the following method which moves the pages to the main form.

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

Events delegates and all of that good stuff work as long as they only reference what is in their form class.

Here is the full code.


//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]);
         }
      }
   }
}


4

2 に答える 2

2

先に進む前に、Composeメソッドをクリーンアップする必要があると思います。なぜコンテナとカタログをバッチに追加するのですか?

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);
}
于 2009-03-19T07:38:44.010 に答える