我正在设计一个支持插件开发的应用程序。它更像是一种学习练习。
加载到我的应用程序中的所有程序集(插件)都包含showPrefs()方法。当我加载每个程序集时,我想为每个程序集分配一个按钮,这样当我单击该按钮时,它会触发按钮所分配到的程序集的showPrefs()方法。
我该怎么做?一个快速而肮脏的解决方案是将showPrefs()方法签名更改为showPrefs(对象发送者,EventArgs e)。这样我可以将它分配给按钮,但我认为这是一个廉价的解决方法。
有什么想法吗?
click事件处理程序只接受具有方法签名(object o,EventArgs e)的委托,所以我不知道如何将showPrefs()方法分配给click事件。
这就是我遇到麻烦了。
答案 0 :(得分:5)
我认为你需要澄清你所说的内容,因为你所要求的内容远比首先加载程序集复杂得多。
完成程序集加载后,您将获得实现接口的类型列表。只需遍历,为每个按钮创建按钮,然后在按钮的单击事件处理程序中运行showPrefs方法。
这是一些c#伪代码:
Button b;
foreach(var i in instancesThatHavePrefsMethods)
{
b = new Button();
b.Click += (o,e) => { i.showPrefs(); };
this.Children.Add(b);
}
一旦我有类型,我可以实例化其中一个,坚持它们。然后我需要做的就是为每个创建一个按钮,添加一个事件处理程序(由伪代码中的lambda创建的机箱保存对正确实例的引用;您也可以创建自己的类来执行此操作或强制执行事件处理程序在你的界面中),然后将按钮添加到表单。
从您的澄清中,有几种不同的方法可以做到这一点。
首先,在您的界面上强制执行事件处理程序:
public interface IPluginKLol
{
//snip
///<summary>An event handler, when fired, calls <seealso cref="showPerfs"/></summary>
void ShowPerfsEventHandler(object o, EventArgs e);
//snip again
}
然后
Button b;
IEnumerable<IPluginKLol> instancesThatHavePrefsMethods = GetPlugins();
foreach(var i in instancesThatHavePrefsMethods)
{
b = new Button();
b.Click += i.ShowPerfsEventHandler;
this.Children.Add(b);
}
或者,您可以创建一个类来将事件转换为调用showPerfs(只是实例化,设置引用,并分配事件处理程序):
public class ShowPerfsBroker
{
public IPluginKLol Victim {get;set;}
public void ShowPerfsEventHandler(object o, EventArgs e)
{
if(Victim == null) return;
Victim.ShowPerfs();
}
}
答案 1 :(得分:3)
如果你看一下Will的伪代码,他会给Click处理程序分配一个lambda表达式,如下所示:
b.Click += (o,e) => { i.showPrefs(); };
这是一个无关紧要的方法,接受一个对象和EventArgs。然后它在接口上调用showPrefs函数。它大致等于以下内容:
b.Click += delegate(Object o, EventArgs e) { i.showPrefs(); };
如果你使用的是c#2.0,这可能会有用。