Является ли + = делегировать {} правильным способом прикрепления настраиваемых аргументов событий к событию элемента управления пользовательского интерфейса?

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

Форма Windows

public Form1()       
{ 

ColorChanges KK = new ColorChanges();

KK.ColorEventHandler += handle_ColorChanges;

button1.Click += delegate { KK.ChangeColor(button1); };

}

Класс события

class ColorChanges
{

   *... properties & constructor*

   public void ChangeColor(object sender)
   {
   *... randomly assign color to ColorEventArgs*
   }

   protected virtual void onColorEvent(object sender, ColorEventArgs e)
   {
      EventHandler<ColorEventArgs> ceh = ColorEventHandler;
      {   
      if (ceh != null)
         {
         ceh(sender, e)             
         }
     }
   }

   public event EventHandler<ColorEventArgs> ColorEventHandler;
}

Настраиваемые аргументы событий

public class ColorEventArgs : EventArgs
{
  public Color xColor { get; set; }
}

Обработчик события

public void handle_ColorChanges(object sender, ColorEventArgs e)
{
   if (sender is Button)
      {
       var ButtonSender = (Button)sender;

       ButtonSender.BackColor = e.xColor;
       }
}

Итак, отредактированные вопросы:

Полезно ли использование делегата EventHandler (TEventArgs)? В документации MS указано, что такой синтаксис, как

  button1.Click += new EventHandler<AutoRndColorEventArgs>(handle_ColorChanges);

правильно, но это не дойдет до моего кода, чтобы случайным образом выбрать цвет и ошибку

«Нет перегрузки для 'handle_ColorChanges' соответствует делегату> 'System.EventHandler'»

так что-то вроде

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));

or

button1.Click += new EventHandler(KK.ChangeColor(button1));

Ошибка говорит о том, что требуется метод, и если я использую

«Нет перегрузки для 'handle_ColorChanges' соответствует делегату 'System.EventHandler'»

Лямбда-выражения помогают благодарим за вспомогательные ответы

button1.Click += (sender,args) => KK.ChangeColor(s); 

Но это не позволяет отменить назначение, и это потребуется позже ...

У анонимного делегата такая же проблема

button1.Click += delegate(object sender, EventArgs e)
            { KK.ChangeColor(sender); };

Суть проблемы в том, что мои методы цвета или их делегаты не соответствуют подписи делегата кнопки (объект, событие). Меня не волнуют аргументы кнопок, и я хочу использовать свои собственные КАК?


person Stephan Luis    schedule 19.03.2014    source источник
comment
Материал new EventHandler является необязательным, начиная с C # 2.0.   -  person CodesInChaos    schedule 19.03.2014
comment
comment
Вопросы различаются в первую очередь потому, что я спрашиваю о добавлении делегата или EventHandler ‹MyArgT›, где MyArgT: EventArgs - это настраиваемые аргументы события и не соответствуют подписи кнопки по умолчанию.   -  person Stephan Luis    schedule 20.03.2014


Ответы (2)


Правильно ли используется делегат?

Да, вы назначаете анонимного делегата < / strong> в качестве обработчика событий. Это совершенно верно, однако уловка здесь в том, что вы не можете отменить назначение обработчика события, потому что у вас нет на него ссылки. Вы можете сохранить ссылку на него и сделать это таким образом (при необходимости)

var clickHandler = delegate { ... };
button1.Click += clickHandler;
...
button1.Click -= clickHandler

Если вам нужен доступ к параметрам обработчика событий, вам нужно будет добавить их в подпись, например.

button1.Click += delegate (object sender, EventArgs args) { ... }

Конструкция new EventHandler(SomeHandlerMethod) - это долгий путь решения задач, он является синонимом += SomeHandlerMethod. Ваш код в настоящее время не работает, потому что вы пытаетесь фактически вызвать обработчик внутри конструктора, когда конструктор ожидает ссылку на метод

+= new EventHandler<ColorEventArgs>(KK.ChangeColor);

Есть ли для этого лучшая структура?

Да, вы можете сделать это, используя даже меньше кода.

button1.Click += (s, args) => KK.ChangeColor(button1);
person James    schedule 19.03.2014

Это неверно:

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1));

Вместо KK.ChangeColor(button1) вам просто нужно указать имя метода обработчика событий, как здесь:

KK.ColorEventHandler += handle_ColorChanges;

Сигнатура метода обработчика событий должна совпадать с делегатом EventHandler. Если вы хотите просто вызвать метод в обработчике событий, вы можете использовать лямбда-выражение следующим образом:

button1.Click += (s,e) => KK.ChangeColor(s);

Or:

button1.Click += delegate(object s, EventArgs e) { KK.ChangeColor(s); };

Делая это, вы создаете анонимный метод и присоединяете его к вашему Click событию.

person Selman Genç    schedule 19.03.2014