#c# #events
#c# #Мероприятия
Вопрос:
Я создавал форму Windows и пытался вручную привязать метод к событию click в MyButton, вот так:
public Form1()
{
InitializeComponent();
myButton.Click = new EventHandler(ShowMessage("You clicked my button!"));
}
private void ShowMessage(string message)
{
MessageBox.Show(message);
}
Как некоторые из вас могут догадаться, компилятору это не понравилось. Я не был уверен, почему, потому что я привык к тому, что могу делать такие вещи в Javascript, как это:
document.getElementById("myButton").onclick = function(){showMessage("You clicked my button")};
function showMessage(message) {
alert(message);
}
Я запутался в этом и в конечном итоге сделал что-то действительно уродливое, связанное с глобальной переменной, подобной этой:
string message = "";
public Form1()
{
InitializeComponent();
message = "You clicked my button!";
myButton.Click = ShowMessage;
}
private void ShowMessage(object sender, EventArgs e)
{
MessageBox.Show(message);
}
Вот мои два вопроса: во-первых, есть ли более чистый способ сделать это? Во-вторых, почему методы событий должны назначаться с помощью =
, а не просто =
?
Комментарии:
1. Попробуйте csharpcomputing.com/Tutorials/Lesson15.htm
Ответ №1:
Обработчики событий должны быть добавлены к событиям с помощью =
, поскольку событие может иметь множество других делегатов, неизвестных вашему конкретному фрагменту кода. Чистое присвоение подразумевало бы возможность удаления других связанных делегатов, на что у вас не должно быть разрешения как у клиента события.
Кроме того, вы, вероятно, захотите воспользоваться преимуществами анонимных делегатов для выполнения любой формы привязки аргументов. Например:
myButton.Click = delegate(object sender, EventArgs e) {
MessageBox.Show("You clicked my button!");
};
Ответ №2:
Вы также можете использовать lambda.
myButton.Click = (sender, e) => {
MessageBox.Show("You clicked my button!");
};
Ответ №3:
Вот мои два вопроса: во-первых, есть ли более чистый способ сделать это?
да, анонимные функции, как и в JavaScript (другой синтаксис)
myButton.Click = delegate(object sender, EventArgs e)
{
MessageBox.Show(message);
};
почему методы событий должны быть
назначается с помощью =, а не просто =?
В противном случае у вас может быть только 1 обработчик событий вместо нескольких для одного и того же события. = часто используется в языке программирования для добавления чего-либо. = используется для присвоения переменной значения.
Комментарии:
1. Одно предостережение при использовании анонимных делегатов; если вы не назначите этот делегат долговременной переменной, вы не сможете отсоединить этот делегат от события. Это потому, что делегаты не проверяются семантически; они приравниваются только по ссылке, и поэтому никакой другой анонимный делегат, даже с точно таким же кодом, не будет иметь той же ссылки, что и прикрепленный.
Ответ №4:
Вы можете ввести myButton.Click = delegate { showmessage("You clicked my button!"); };
Ответ №5:
Поскольку может быть добавлено более одного обработчика, как в вашем коде javascript, в onclick будет вызываться только одна функция.
Пример:
myButton.Click = ShowMessage;
myButton.Click = LogToFile;
Обе функции ShowMessage и LogToFile будут вызываться при нажатии кнопки. Именно это пытается указать » » в » =». Вы добавляете к обработчику, а не заменяете его.
Что касается упрощения, вы могли бы использовать анонимные lamda, чтобы помочь like, но обратите внимание, что это затрудняет отсоединение / удаление обработчиков позже (если это важно).
myButton.Click = new EventHandler( (sender,e) => ShowMessage("You clicked my button!") );
Ответ №6:
Попробуйте это решение, чтобы обойти необходимость глобальной переменной с возможностью использования именованного метода многократного использования для вашего обработчика событий:
private void ShowMessage(object sender, EventArgs e, string message)
{
MessageBox.Show(message);
}
public Form1()
{
InitializeComponent();
myButton.Click = delegate(object sender, EventArgs e)
{
ShowMessage(sender,e,"You clicked my button!");
};
}