Пользовательские обработчики событий C #
-
03-07-2019 - |
Вопрос
Если у меня есть свойство:
public list<String> names { get; set; }
Как я могу генерировать и обрабатывать пользовательское событие для аргументов, называемых onNamesChanged, всякий раз, когда имя добавляется в список?
Решение
Вы должны ознакомиться с System.ComponentModel.BindingList , в частности, событие ListChanged .
Другие советы
BindingList, вероятно, ваш лучший вариант, поскольку он имеет встроенное отслеживание изменений и множество существующих событий, которые вы можете использовать. Ниже приведен пример предоставления настраиваемого события для Add, которое пересылается в событие BindingList.
class Example
{
private BindingList<string> m_names = new BindingList<string>();
public IEnumerable<string> Names { get { return m_names; } }
public event AddingNewEventHandler NamesAdded
{
add { m_names.AddingNew += value; }
remove { m_names.AddingNew -= value; }
}
public void Add(string name)
{
m_names.Add(name);
}
}
Одной из альтернатив BindingList является ObservableCollection - в этом случае вы ' хочу подписать собственный обработчик событий на CollectionChanged и запустить событие в зависимости от действия.
Дэвид Мохундро показывает один подход; Еще один вариант - наследовать от Collection < T > и переопределить различные методы:
class Foo {}
class FooCollection : Collection<Foo>
{
protected override void InsertItem(int index, Foo item)
{
// your code...
base.InsertItem(index, item);
}
protected override void SetItem(int index, Foo item)
{
// your code...
base.SetItem(index, item);
}
// etc
}
Наконец, вы можете создать свой собственный список (IList, IList < T >) из первых принципов - много работы, мало пользы.
Неортодоксальный подход может заключаться в использовании AOP-фреймворка, такого как PostSharp, для " weave " обработчик до / после вызова метода доступа, который инициирует событие.
Вы создаете внешний класс, который содержит код предварительной и / или последующей обработки для доступа к вашему свойству, проверяет, изменилось ли значение свойства между pre и post, и вызывает событие.
Имейте в виду, что, принимая значение для сравнения (внутри кода вашего обработчика), вы можете попасть в бесконечный цикл (вы вызываете метод доступа к свойству, который вызывает обработчик AOP, который вызывает метод доступа и т. д.), поэтому вам может потребоваться отразить в классе, содержащем это свойство, чтобы получить вспомогательное поле.
Вам не нужно показывать список напрямую как свойство, и, возможно, ваш класс реализует IList или что-то подобное, после чего ваш обработчик событий запускается методом Add ().