如何在 C# 中将项目添加到集合之前触发事件?
我想在将项目添加到 BindingList 之前进行一些处理。我看到有一个 ListChanged 事件,但在添加项目后会触发该事件。 AddNew 事件仅在调用 AddNew 方法(而不是 Add 方法)时触发。以前有人做过这样的事情吗?
更新:
我创建了以下类,当在 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());
}
}
I would like to do some processing before an item is added to a BindingList. I see there is an ListChanged event but this is fired after the item is added. The AddingNew event is only fired when the AddNew method (not the Add method) is called. Has anyone done something like this before?
UPDATE:
I have created the following classes and when the Add method is called on the IList, my new Add method gets triggered. So, do I have the casting problem that I've read in other places? If I removed the ISpecialCollection interface from the collection, my Add method doesn't get called. Can someone explain why it's acting differently? Do I have the casting problem if I use the ISpecialCollection< interface?
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());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您应该重写受保护的
BindingList.InsertItem
方法 (MSDN )。Add
、Insert
等都调用此函数来执行实际的添加操作并引发适当的事件。引发您的事件,然后调用base.InsertItem
来完成其余的工作。You should override the protected
BindingList.InsertItem
method (MSDN).Add
,Insert
and such all call this to do the actual adding adding and raise appropriate events. Raise your event, and then callbase.InsertItem
to do the rest.最直接的途径是对
Collection
类进行子类化。这是 BCL 中的集合类,它被设计为子类化并覆盖其行为。子类化其他类型(例如BindingList
或List
)只会给您带来痛苦。一旦您对
Collection
进行子类化,您就可以重写 Add 并创建您自己的事件来侦听。The most straightforward route is to subclass the
Collection<T>
class. This is the collection class in the BCL which is designed to be subclassed and have it's behavior overriden. Subclassing other types likeBindingList<T>
orList<T>
will just cause you pain.Once you subclass
Collection<T>
, you can override Add and create your own event to listen to.我做了类似的事情,因为我需要捕获 ItemAdding 和 ItemAdded 事件
魔法位是新关键字,它将覆盖继承类的方法
I have done something similar as I needed to capture the ItemAdding and ItemAdded event
The magic bit is the new keyword that will override the inherited class' method
像这样的东西:
Something like:
正确的方法是扩展
Collection
并覆盖
InsertItem
< /a> 方法。您可以在调用 base.InsertItem 之前在那里引发事件。The right way to do this is to extend
Collection<T>
and override theInsertItem
method. You can raise your event there before calling base.InsertItem.使用 C5 集合库。
C5
的集合已设置为能够在多个操作上触发事件,包括清除集合、添加项目、删除项目、插入项目和常规集合更改。此外,C5 库集合在适当的情况下实现了 System.Collection.Generic
ICollection
和IList
接口,因此可以作为即使库仅需要实现,例如SCG.ICollection
。编辑:我忘了提及您的部分要求;我上面提到的许多事件都是可取消的事件,并且在操作影响底层集合之前触发,允许您进行更改或拒绝添加、删除等。
Use the C5 collections library.
C5
's collections are already set up to be able to fire events on several operations, including clearing the collection, adding items, removing items, inserting items, and general collection changes.As well, the C5 library collections implement the
System.Collection.Generic
ICollection
andIList
interfaces where appropriate, and so can be dropped in as the implementation even if a library is only expecting, e.g. anSCG.ICollection
.EDIT: I forgot to mention a portion of your requirements; many of those events I mentioned above are cancelable events, and are fired before the action has affected the underlying collection, allowing you to make changes or reject additions, removals, etc.
使用可观察集合。它具有监视集合何时更改的事件。我相信它主要用于 WPF,但我也将它用于 ASP.NET 项目。
Use ObservableCollection. It has events that monitor when the collection is changing. I believe that it is primarily used for WPF, but I have used it with ASP.NET projects also.