WedX - журнал о программировании и компьютерных науках

c# — назначение методов динамически создаваемым элементам управления

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

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

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

Любые идеи?


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

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


Ответы:


1

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

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

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

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

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

12.01.2009
  • Этот ответ проще всего реализовать, хотя мне также нравится Уиллс. Огромное спасибо, ребята. 12.01.2009

  • 2

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

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

    Вот некоторый псевдокод С#:

    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();
      }
    }
    
    12.01.2009
  • Однако будьте осторожны с доступом к модифицированному закрытию. В вашем первом примере, когда итерация IEnumerable завершена, я укажу на последний элемент в коллекции. Когда кнопка затем будет нажата, она, скорее всего, вызовет showPrefs только для последнего элемента. 08.11.2012
  • @DanielPops: Знаете, я верил, что вы правы, но я запустил крошечное приложение, чтобы проверить это, и оно не помогло. Самая ранняя версия, на которую я нацеливался, была 3.5, так что, по крайней мере, с этого момента компилятор гарантирует, что вы не наступите на свой собственный придурок. 08.11.2012
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]