c # - назначение методов динамически создаваемым элементам управления - PullRequest
1 голос
/ 12 января 2009

Я разрабатываю приложение, которое поддерживает разработку плагинов. Это скорее учебное упражнение.

Все сборки (плагины), загружаемые в мое приложение, содержат метод showPrefs (). Когда я загружаю каждую сборку, я хочу назначить кнопку для каждой, чтобы при нажатии на кнопку запускался метод showPrefs () сборки, которой назначена кнопка.

Как мне это сделать? Быстрое и грязное решение было бы изменить сигнатуру метода showPrefs () на showPrefs (отправитель объекта, EventArgs e). Таким образом, я могу назначить его кнопке, но я думаю, что это дешевый обходной путь.

Есть идеи?


Обработчик события click принимает только делегатов, имеющих сигнатуру метода (object o, EventArgs e), поэтому я не знаю, как бы назначить метод showPrefs () для события click.

С этим у меня проблемы.

Ответы [ 2 ]

5 голосов
/ 12 января 2009

Я думаю, вам нужно уточнить, о чем вы говорите, поскольку то, о чем вы спрашиваете, гораздо проще, чем загружать сборки в первую очередь.

После завершения загрузки сборки у вас будет список типов, которые реализуют ваш интерфейс. Просто итерируйте, создавая кнопки для каждого, и в обработчике события click для кнопки запустите ваш метод showPrefs.

Вот какой-то псевдокод c #:

Button b;
foreach(var i in instancesThatHavePrefsMethods)
{
  b = new Button();
  b.Click += (o,e) => { i.showPrefs(); };
  this.Children.Add(b);
}

Когда у меня есть типы, я могу создать экземпляр каждого из них, держась за них. Затем все, что мне нужно сделать, это создать кнопку для каждого, добавить обработчик события (оболочка, созданная лямбда-выражением в псевдокоде, содержит ссылку на правильный экземпляр; вы можете альтернативно создать свой собственный класс для этого или назначить обработчик события в вашем интерфейсе), а затем добавьте кнопку в форму.


Из вашего пояснения есть несколько разных способов сделать это.

Во-первых, назначьте обработчик событий в вашем интерфейсе следующим образом:

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();
  }
}
3 голосов
/ 12 января 2009

Если вы посмотрите на псевдокод Уилла, он назначает лямбда-выражение для обработчика Click, например:

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

Это какой-то необычный метод, принимающий объект и EventArgs. Затем он вызывает вашу функцию showPrefs на интерфейсе. Это примерно равно следующему:

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

Что может быть полезно, если вы используете c # 2.0.

...