Winforms с MEF - PullRequest
       34

Winforms с MEF

1 голос
/ 18 марта 2009

У меня есть приложение winforms, которое использует различные вкладки. Я хотел бы использовать MEF, чтобы иметь возможность добавлять больше вкладок, которые импортируются при запуске. Мне трудно понять, как это сделать.

Edit: Вот что я сделал.

Я взял основной класс winforms и разложил его так, чтобы в нем был только TabControl, который я открываю для каждой вкладки через интерфейс. Затем я также создаю второй интерфейс ITab, который я использую с MEF, чтобы получить вкладку, а затем добавляю его в основной 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 ]

2 голосов
/ 19 марта 2009

Прежде чем двигаться дальше, я думаю, что ваш метод 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);
}
0 голосов
/ 19 марта 2009

Вот версия, которая является общей и позволяет вам менять форму winforms с другой, используя Mef. Существует интерфейс IForm, который предоставляется с использованием Mef, и он имеет один метод public void MoveForm (форма формы), и он копирует новую форму поверх старой формы.

Вот код.



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



...