#c# #events
#c# #Мероприятия
Вопрос:
Итак, у меня есть класс, который в основном является менеджером для более чем 20 копий другого класса. Каков наилучший способ обработки одного и того же события, запущенного из каждого из них? И это лучший способ отменить регистрацию событий? Или я должен каким-то образом использовать один обработчик событий?
Я собрал простой пример, который в основном делает то, что я делаю в моем реальном проекте.
class Manager
{
List<Child> children = new List<Child>();
public Manager()
{
for (int i = 0; i < 10; i )
{
Childchild = new Child();
child.Done = child_Done;
items.Add(child);
child.DoStuff();
}
}
public void RemoveAll()
{
foreach (Child child in items)
{
child.Done -= child_Done;
}
items.Clear();
}
void child_Done(string sometext)
{
Console.WriteLine("child done: " sometext);
}
}
class Child
{
public delegate void _Done(string sometext);
public event _Done Done;
public Child()
{
}
public void DoStuff()
{
if (Done != null) { Done("finally!"); }
}
}
Ответ №1:
Отмена регистрации должна быть в порядке — до тех пор, пока целевой экземпляр и метод совпадают, он будет работать. Однако я настоятельно рекомендую вам использовать более обычный шаблон событий с a sender
— тогда вы будете знать, какой дочерний элемент разговаривает. Например:
public class MessageEventArgs : EventArgs {
public MessageEventArgs(string message) {
this.message = message;
}
private readonly string message;
public string Message { get { return message; } }
}
и:
public event EventHandler<MessageEventArgs> Done;
protected virtual void OnDone(string message) {
var handler = Done;
if(handler != null) handler(this, new MessageEventArgs(message));
}
Ответ №2:
Предполагая, что вы хотите, возможно, было бы лучше добавить объект Manager для ответа каждому дочернему объекту, когда дочерний объект вызывает событие:
Возможно, было бы лучше зарегистрироваться для события при добавлении дочернего элемента и отменить регистрацию при удалении дочернего элемента.
Быстрый способ сделать это — переключиться с List на ObservableCollection . Эта коллекция вызовет событие, как только коллекция изменится.
Итак, в конструкторе менеджера создайте экземпляр ObservableCollection и зарегистрируйтесь для события CollectionChanged . В обработчике проверьте аргумент события, чтобы увидеть, какие дочерние элементы были добавлены и удалены, чтобы менеджер мог зарегистрировать (или отменить регистрацию) их событие (события).
Ответ №3:
Это более или менее так.
Несколько предложений, чтобы заставить его работать немного лучше:
- Создайте функцию, которая добавляет дочерний элемент и одновременно регистрирует событие.
То же самое можно сделать с удалением дочернего элемента отменой регистрации события. - Кроме того, вы можете заставить событие получить параметр «sender» и заставить дочерний элемент передать ему «this». Таким образом, обработчик событий сможет узнать, какой дочерний элемент выполнен, и удалить его из списка, и / или что еще нужно сделать.