5

我想在将项目添加到 BindingList 之前进行一些处理。我看到有一个 ListChanged 事件,但这是在添加项目后触发的。仅当调用 AddNew 方法(而不是 Add 方法)时才会触发 AdditionalNew 事件。有没有人做过这样的事情?

更新:

我创建了以下类,当在 IList 上调用 Add 方法时,我的新 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());
  }
}
4

7 回答 7

3

最直接的方法是对类进行子Collection<T>类化。这是 BCL 中的集合类,它被设计为子类并覆盖其行为。子类化其他类型,例如BindingList<T>orList<T>只会让您感到痛苦。

子类化Collection<T>后,您可以覆盖 Add 并创建自己的事件来收听。

于 2009-11-04T15:53:21.747 回答
3

您应该覆盖受保护的BindingList.InsertItem方法 ( MSDN )。AddInsert并且所有这些都调用它来执行实际的添加添加并引发适当的事件。提出您的事件,然后调用base.InsertItem以完成其余的工作。

于 2009-11-04T16:02:22.783 回答
2

我已经做了类似的事情,因为我需要捕获 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();
    }
于 2009-11-04T15:52:33.660 回答
1

就像是:

  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));
            }
        }
    }
于 2009-11-04T14:53:03.360 回答
0

使用C5集合库。C5的集合已经设置为能够在多个操作上触发事件,包括清除集合、添加项目、删除项目、插入项目和一般集合更改。

同样,C5 库集合在适当的情况下实现了System.Collection.Generic ICollectionIList接口,因此即使库只是期望的,也可以作为实现放入,例如SCG.ICollection.

编辑:我忘了提及您的部分要求;我上面提到的许多事件都是可取消的事件,并且在操作影响基​​础集合之前被触发,允许您进行更改或拒绝添加、删除等。

于 2009-11-05T17:33:44.487 回答
0

正确的方法是扩展Collection<T>和覆盖该InsertItem方法。您可以在调用 base.InsertItem 之前在那里引发您的事件。

于 2009-11-04T16:13:55.230 回答
-1

使用 ObservableCollection。它具有监视集合何时更改的事件。我相信它主要用于 WPF,但我也将它用于 ASP.NET 项目。

于 2010-01-17T04:17:53.417 回答