Обработчики событий в c # - синтаксис / шаблон - PullRequest
6 голосов
/ 09 ноября 2011

Я новичок в c #, поэтому извиняюсь, если это нубский вопрос. Я пытаюсь прояснить синтаксис или шаблон для обработки событий в C #.

Итак, у меня есть Form объект Form1 и Button button1 в форме. Я обрабатываю событие Click с помощью такого метода в Form1.cs:

private void button1_Click(object sender, EventArgs e)
{
    Debug.WriteLine("click!");
}

, который работает нормально. Теперь в другой форме Form2 у меня есть TreeView treeView1, и я хочу обработать событие BeforeExpand. Поэтому я предположил, что это будет:

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
     Debug.WriteLine("Hello!");
}

, который фактически не работает: этот метод никогда не вызывается, когда я раскрываю узел. Но несколько ответов SO подразумевают, что - это способ сделать это, например, этот один .

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

treeView1.BeforeExpand += new TreeViewCancelEventHandler(anyMethodNameYouLike);

Так в чем же разница между этими двумя подходами? Почему синтаксис _event не работает для дерева? Есть ли разница между типами событий?

Спасибо

Ответы [ 7 ]

5 голосов
/ 09 ноября 2011

Полагаю, вы дважды щелкнули кнопку в конструкторе Visual Studio.Обработчик button1_Click был добавлен автоматически, точно так же, как вы вручную создали обработчик BeforeExpand.

Проверьте ваш файл Form1.Designer.cs, вы увидите строку примерно так:

this.button1.Click += new System.EventHandler(this.button1_Click);
5 голосов
/ 09 ноября 2011

Вам нужны обе вещи:
1) метод, который может обрабатывать тип рассматриваемого события. Для делегата TreeViewCancelEventHandler ( MSDN ) правильная сигнатура метода:

public void MyMethodNameGoesHere(Object sender,TreeViewCancelEventArgs e)
{
  // do some impressive stuff here
}

2) Вы должны зарегистрироваться для участия в мероприятии:

treeView1.BeforeExpand += new TreeViewCancelEventHandler(MyMethodNameGoesHere);

Вы также можете использовать только имя метода:

treeView1.BeforeExpand += MyMethodNameGoesHere;

И в качестве последней альтернативы вы можете использовать этот «встроенный» синтаксис для небольших функций:

treeView1.BeforeExpand += (sender, e) =>
{
    // do a bit of magic here
};

Что может быть полезно знать, так это то, что регистрации обработчиков не «складываются» (извините за плохую формулировку, предложения по улучшению очень приветствуются!). Это означает, что при выполнении следующих действий вы не будете получать дальнейшие события после выполнения последней строки:

treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand += MyMethodNameGoesHere;
treeView1.BeforeExpand -= MyMethodNameGoesHere; // note the MINUS sign
4 голосов
/ 09 ноября 2011

То, что у вас есть, правильно.Вам нужно добавить обработчик к событию, как вы это делали во втором случае.

Должна быть строка наподобие этой:

button1.Click += button1_Click;

(возможно с оболочкой new EventHandler()) где-то в вашем Form1 коде, скорее всего в файле .designer.cs.

1 голос
/ 09 ноября 2011

В WinForms вы можете связывать обработчики событий из конструктора, используя панель инструментов «Свойства» и нажимая кнопку молнии вверху.Это откроет вкладку событий.Просто дважды щелкните по названию события, чтобы сгенерировать обработчик в вашем коде, или выберите существующий метод с правильной подписью из выпадающего списка.Это фактически сгенерирует код «+ =» для вас в файле .designer.

Имя Control_Event генерируется автоматически.Однако вы можете использовать любое имя для своих обработчиков и даже зарегистрировать более одного.

1 голос
/ 09 ноября 2011

Система обработки событий C # не работает при каких-либо соглашениях об именах (я думаю, вы можете поверить, что это так?).Метод с именем treeView1_BeforeExpand не будет вызываться для события BeforeExpand дерева view1, если только вы не скажете ему вызвать этот метод для этого конкретного события.

В приведенном ниже коде написано, что «когда происходит событие BeforeExpand, вызовите метод anyMethodNameYouLike.

treeView1.BeforeExpand += new TreeViewCancelEventHandler(anyMethodNameYouLike);

Вы должны написать свой метод anyMethodNameYouLike.

1 голос
/ 09 ноября 2011

Первый синтаксис, который вообще не является синтаксисом, - это просто соглашение об именах для обработчиков событий. То, что вы делаете со вторым синтаксисом, это настройка делегата для обработчика событий и добавление его к этому событию.

Если вы выберете «Форма 1» и нажмете кнопку «Выбор» и посмотрите на свойства ее событий, событие, скорее всего, будет подключено через конструктор. Вы можете сделать то же самое с TreeView в его форме через конструктор.

0 голосов
/ 09 ноября 2011

Это правильный способ подписаться на событие.Дизайнер автоматически добавляет эту строку в файл .designer.cs, когда вы подписываетесь на событие через него.

В любом случае, эта строка кода где-то записывается.Разница в том, что на одно событие подписывается дизайнер, а на другое вы подписываетесь вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...