Пользовательские обработчики событий C # - PullRequest
7 голосов
/ 20 октября 2008

Если у меня есть недвижимость:

public list<String> names { get; set; }

Как я могу генерировать и обрабатывать пользовательское событие для аргументов, называемых onNamesChanged, всякий раз, когда имя добавляется в список?

Ответы [ 6 ]

13 голосов
/ 20 октября 2008

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);
        }
    }
10 голосов
/ 20 октября 2008

Одной альтернативой BindingList является ObservableCollection - в этом случае вы захотите подписать свой собственный обработчик события на CollectionChanged и запускать его в зависимости от действия.

10 голосов
/ 20 октября 2008

Вы должны проверить System.ComponentModel.BindingList , в частности, событие ListChanged .

0 голосов
/ 20 октября 2008

Неортодоксальный подход мог бы использовать платформу AOP, такую ​​как PostSharp, для «переплетения» обработчика до / после вызова метода доступа, который запускает событие.

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

Имейте в виду, что, принимая значение для сравнения (внутри кода вашего обработчика), вы можете попасть в бесконечный цикл (вы вызываете метод доступа к свойству, который вызывает обработчик AOP, который вызывает метод доступа и т. Д.), Поэтому вам может потребоваться отразить в классе, содержащем это свойство, чтобы получить вспомогательное поле.

0 голосов
/ 20 октября 2008

Дэвид Мохундро показывает один подход; Еще один вариант - наследовать от Collection и переопределять различные методы:

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 ) из первых принципов - много работы, мало пользы.

0 голосов
/ 20 октября 2008

Вам не нужно показывать список напрямую как свойство, и, возможно, ваш класс реализует IList или что-то подобное, после чего ваш обработчик событий запускается методом Add ().

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