先创建下图的一个窗体,插件下没添加项目,是留给反射加载.dll插件的。在debug目录下加一个Plugin文件夹,将插件的.dll文件放在此文件夹下可以生效。
给方案添加一个单独的项目来写规范插件的接口,因为需要生成一个.dll给写插件的人调用
接口的代码如下:
using System.Windows.Forms;
namespace NotePad.PluginInterface
{
public delegate TextBox GetTextBoxDelegate();
public interface NotePadPluginInterface
{
//string Name { get; }
//void Run(System.Windows.Forms.TextBox textBox);
//这个接口可以只要表示插件名称Name属性,和功能的Run(Textbox textbox)的方法,
//在主程序根据Name生成ToolStripMenuItem,并绑定事件,然后执行Run。
//但是把ToolStripMenuItem给接口,插件可以实现更复杂的ToolStripMenuItem
ToolStripMenuItem[] Items
{
get;
set;
}
TextBox textbox
{
get;
set;
}
event GetTextBoxDelegate GetTextBoxEvent;//用来获取当前的textbox
void Initize();//生成ToolStripMenuItem,并绑定事件等。
}
}
窗体加载插件的代码
using NotePad.PluginInterface;
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace NotePad
{
public partial class NotePad : Form
{
public NotePad()
{
InitializeComponent();
}
private void NotePad_Load(object sender, EventArgs e)
{
string path = Assembly.GetExecutingAssembly().Location;
string addtions = Path.Combine(Path.GetDirectoryName(path), "Plugin");
string[] dlls = Directory.GetFiles(addtions, "*.dll");//获取插件.dll文件
foreach (string dll in dlls)
{
Assembly assenmbly = Assembly.LoadFile(dll);//加载指定路径上的程序集文件的内容
Type[] types = assenmbly.GetExportedTypes();//获取此程序集中定义的Public类型
Type typeNotePadExtInterface = typeof(NotePadPluginInterface);
foreach (Type type in types)
{
//验证类型实现了NotePadExtInterface接口并且可以实例化
if (typeNotePadExtInterface.IsAssignableFrom(type) && !type.IsAbstract)
{
NotePadPluginInterface notePadEx = (NotePadPluginInterface)Activator.CreateInstance(type);//创建插件实例
notePadEx.Initize();//先初始化插件里的Item
this.PluginToolStripMenuItem.DropDownItems.AddRange(notePadEx.Items);//将插件里定义的Item加为窗体 "插件"项的子项
notePadEx.GetTextBoxEvent += NotePadEx_GetTextBoxEvent;
}
}
}
}
private TextBox NotePadEx_GetTextBoxEvent()
{
return textBox1;
}
}
}
写插件
在插件的项目里引用规范插件的接口的程序集
插件的代码如下:
using NotePad.PluginInterface;
using System;
using System.Windows.Forms;
namespace NotePadPlugin
{
public class NotePadPlugin: NotePadPluginInterface
{
public ToolStripMenuItem[] Items
{
get;
set;
}
public TextBox textbox
{
get;
set;
}
public event GetTextBoxDelegate GetTextBoxEvent;
public void Initize()
{
ToolStripMenuItem switchCaseItem = new ToolStripMenuItem();
switchCaseItem.Text = "切换大小写";
ToolStripMenuItem ToUpperItem = new ToolStripMenuItem();
ToUpperItem.Text = "大写";
ToUpperItem.Click += ToUpperItem_Click;
ToolStripMenuItem ToLowerItem = new ToolStripMenuItem();
ToLowerItem.Text = "小写";
ToLowerItem.Click += ToLowerItem_Click;
switchCaseItem.DropDownItems.AddRange(new ToolStripMenuItem[] { ToUpperItem, ToLowerItem });
ToolStripMenuItem clearTextItem = new ToolStripMenuItem();
clearTextItem.Text = "清空";
clearTextItem.Click += ClearText_Click;
ToolStripMenuItem colorItem = new ToolStripMenuItem();
colorItem.Text = "颜色";
colorItem.Click += ColorItem_Click; ;
Items = new ToolStripMenuItem[] { switchCaseItem, clearTextItem,colorItem };
}
private void ColorItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
using (ColorDialog colorDialog = new ColorDialog())
{
if (colorDialog.ShowDialog() == DialogResult.OK)
{
textbox.ForeColor = colorDialog.Color;
}
}
}
private void ClearText_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = "";
}
private void ToLowerItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = textbox.Text.ToLower();
}
private void ToUpperItem_Click(object sender, EventArgs e)
{
textbox = GetTextBoxEvent();
textbox.Text = textbox.Text.ToUpper();
}
}
}
将插件的项目生成的dll文件放在NotePad程序Plugin文件夹下之后,运行程序可以看到插件下多了子项,而且功能都实现了。