Как я могу запустить событие до добавления элемента в коллекцию на С#?

Я хотел бы сделать некоторую обработку до того, как элемент будет добавлен в BindingList. Я вижу, что есть событие ListChanged, но оно запускается после добавления элемента. Событие AddingNew запускается только при вызове метода AddNew (а не метода Add). Кто-нибудь сделал что-то подобное раньше?

UPDATE:

Я создал следующие классы, и когда метод Add вызывается в IList, мой новый метод Add запускается. Итак, у меня есть проблема кастинга, которую я читал в других местах? Если я удалил интерфейс ISpecialCollection из коллекции, мой метод Add не будет вызван. Может кто-нибудь объяснить, почему это действует по-другому? У меня есть проблема с литьем, если я использую ISpecialCollection < интерфейс?

public interface ISpecialCollection<t> : IList<t> { } public class SpecialCollection<t> : BindingList<t>, ISpecialCollection<t> { public new void Add (T item) { base.Add(item); } } class Program { static void Main(string[] args) { IList<itemtype> list = new SpecialCollection<itemtype>(); list.Add(new ItemType()); } } </itemtype>
                            </itemtype>
                        </t>
                    </t>
                </t>
            </t>
        </t>
7 ответов

Вы должны переопределить защищенный метод BindingList.InsertItem (MSDN). Add, Insert, и все это вызывает это, чтобы добавить добавление и поднять соответствующие события. Поднимите свое событие, а затем вызовите base.InsertItem, чтобы сделать остальные.


Самый простой путь - подкласс класса Collection. Это класс коллекции в BCL, который разработан для подкласса и его поведение переоценивается. Подклассификация других типов, таких как BindingList или List, просто вызовет у вас боль.

После подкласса Collection вы можете переопределить Добавить и создать свое собственное событие для прослушивания.


Я сделал что-то похожее, так как мне нужно было захватить событие ItemAdding и ItemAdded

Магический бит - это новое ключевое слово, которое переопределит метод унаследованного класса

// class that inherits generic List and hides the add item
public class ListWithEvents<t> : List<t>
 {
 public event EventHandler ItemAdding;
 public event EventHandler ItemAdded;
 public new void Add(T item)
 {
 if (ItemAdding != null)
 ItemAdding(item, EventArgs.Empty);
 base.Add(item);
 if (ItemAdded != null)
 ItemAdded(item, EventArgs.Empty);
 }
 }
// Using the class
protected override void OnLoad(EventArgs e)
 {
 ListWithEvents<int> lstI = new ListWithEvents<int>();
 lstI.ItemAdded += new EventHandler(lstI_ItemAdded);
 lstI.ItemAdding += new EventHandler(lstI_ItemAdding);
 }
 void lstI_ItemAdding(object sender, EventArgs e)
 {
 throw new NotImplementedException();
 }
 void lstI_ItemAdded(object sender, EventArgs e)
 {
 throw new NotImplementedException();
 }
</int></int></t></t>


Что-то вроде:

public class PreProcessBindingList<t> : Collection<t>
 { 
 public AddingNewEventHandler AddingNew;
 public override void Add(T item)
 {
 PreProcess(item);
 base.Add(item);
 AddingNewEventHandler addingNew = this.AddingNew;
 if (addingNew != null)
 {
 addingNew(this, new AddingNewEventArgs(item));
 }
 }
 }
</t></t>


Правильный способ сделать это: Collection и переопределить InsertItem. Вы можете поднять свое событие там до вызова base.InsertItem.


Используйте библиотеку коллекций C5. Коллекции C5 уже настроены, чтобы иметь возможность запускать события на нескольких операциях, включая очистку коллекции, добавление элементов, удаление элементов, вставку элементов и общие изменения коллекции.

Кроме того, коллекции C5-библиотеки реализуют интерфейсы System.Collection.Generic ICollection и IList, где это необходимо, и поэтому могут быть удалены в качестве реализации, даже если библиотека ожидает только, например. a SCG.ICollection.

EDIT: я забыл упомянуть о части ваших требований; многие из тех событий, о которых я упоминал выше, являются отменными событиями и увольняются до того, как действие повлияло на базовую коллекцию, что позволяет вам вносить изменения или отклонять добавления, удаления и т.д.


Использовать ObservableCollection. Он имеет события, которые отслеживают, когда коллекция меняется. Я считаю, что он в основном используется для WPF, но я также использовал его с проектами ASP.NET.

licensed under cc by-sa 3.0 with attribution.