Winform 与 MEF
我有一个使用不同选项卡的 winforms 应用程序。 我想使用 MEF 来添加更多在启动时导入的选项卡。 我很难弄清楚如何去做这件事。
编辑: 这就是我所做的。
我采用了主要的 winforms 类并将其精简,以便其中只有一个 TabControl,我通过接口向每个 TabPage 公开。 然后,我还创建了第二个界面 ITab,我将其与 MEF 一起使用来获取选项卡页,然后将其添加到主选项卡控件中。 要创建新的选项卡页,我只需添加一个新表单,然后向其中添加一个选项卡控件并设计选项卡页。 我将 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]);
}
}
}
}
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]);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在继续之前,我认为您的 Compose 方法需要清理一下。 为什么要将容器和目录添加到批次中?
AddExportedObject 用于添加预先存在的对象实例作为导出,尝试使用容器和目录作为导出没有多大意义
Before moving on I think your Compose method needs to be cleaned up. Why are you adding the container and catalog into the batch?
AddExportedObject is used to add a pre-existing object instance as an export and it doesn't make much sense trying to use the container and catalog as exports
这是一个通用版本,允许您使用 Mef 将 winforms 表单替换为另一个版本。 有一个使用 Mef 公开的 IForm 接口,它有一个名为 public void MoveForm(Form form) 的方法,它将新表单复制到旧表单上。
这是代码。
Here is a version that is generic and allows you swap out your winforms form with another using Mef. There is an IForm interface that is exposed using Mef and it has one method called public void MoveForm(Form form) and it copies the new form over the old form.
Here is the code.