1

我正在设计一个支持插件开发的应用程序。它更多的是一种学习练习。

加载到我的应用程序中的所有程序集(插件)都包含一个 showPrefs() 方法。当我加载每个程序集时,我想为每个程序集分配一个按钮,以便当我单击该按钮时,它会触发该按钮分配到的程序集的 showPrefs() 方法。

我该怎么做呢?一个快速而肮脏的解决方案是将 showPrefs() 方法签名更改为 showPrefs(object sender, EventArgs e)。这样我可以将它分配给按钮,但我认为这是一个便宜的解决方法。

有任何想法吗?


click 事件处理程序只接受具有 (object o, EventArgs e) 方法签名的委托,所以我不知道如何将 showPrefs() 方法分配给 click 事件。

这就是我遇到的麻烦。

4

2 回答 2

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();
  }
}
于 2009-01-12T11:28:25.563 回答
3

如果您查看 Will 的伪代码,他会为 Click 处理程序分配一个 lambda 表达式,如下所示:

b.Click += (o,e) => { i.showPrefs(); };

这是一个任意的方法,接受一个对象和 EventArgs。然后它会在界面上调用您的 showPrefs 函数。它大致等于以下内容:

b.Click += delegate(Object o, EventArgs e) { i.showPrefs(); };

如果您使用的是 c# 2.0,这可能会很有用。

于 2009-01-12T11:47:47.740 回答