的ObservableCollection:调用OnCollectionChanged有多个新项目 [英] ObservableCollection : calling OnCollectionChanged with multiple new items
问题描述
请注意,我试图用NotifyCollectionChangedAction.Add操作而不是.reset段。后者的工作,但它是不是很有效的大集合。
please note that I am trying to use NotifyCollectionChangedAction.Add action instead of .Reset. the latter does work, but it is not very efficient with large collections.
所以我子类的ObservableCollection:
so i subclassed ObservableCollection:
public class SuspendableObservableCollection<T> : ObservableCollection<T>
由于某种原因,这个code:
for some reason, this code:
private List<T> _cachedItems;
...
public void FlushCache() {
if (_cachedItems.Count > 0) {
foreach (var item in _cachedItems)
Items.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, (IList<T>)_cachedItems));
}
}
是扔
集合添加的事件是指不属于集合项目的
is throwing A collection Add event refers to item that does not belong to collection
这似乎是BCL的错误吗?
this appears to be a bug in BCL ?
我可以逐步并在调用OnCollectionChanged新的项目添加到this.Items见
I can step through and see prior to calling OnCollectionChanged that new items are added to this.Items
WOW
刚刚作出了一个惊人的发现。这些方法都没有工作对我来说(冲洗,的AddRange),因为这个错误似乎是触发仅当此集合绑定到我列表视图!
just made a staggering discovery. None of these approaches worked for me (flush, addrange), because the error appears to be triggered ONLY if this collection is bound to my Listview!!
TestObservableCollection<Trade> testCollection = new TestObservableCollection<Trade>();
List<Trade> testTrades = new List<Trade>();
for (int i = 0; i < 200000; i++)
testTrades.Add(t);
testCollection.AddRange(testTrades); // no problems here..
_trades.AddRange(testTrades); // this one is bound to ListView .. BOOOM!!!
在最后,的ObservableCollection确实支持增加增量名单,但一个ListView没有。 Andyp想出了一个解决方法,使其与下面的CollectionView工作,但由于.REFRESH()被调用,这是没有不仅仅是调用不同的OnCollectionChanged(.reset段)。
In conclusion, ObservableCollection does support adding incremental lists, but a ListView doesn't. Andyp figured out a workaround to make it work with CollectionView below, but since .Refresh() is called, that is no different than just calling OnCollectionChanged( .Reset )..
推荐答案
您可以像这样的ObservableCollection实现的AddRange()如图所示的这里:
you can implement AddRange() for the ObservableCollection like this as shown here:
public class RangeObservableCollection<T> : ObservableCollection<T>
{
private bool _SuppressNotification;
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChangedMultiItem(
NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handlers = this.CollectionChanged;
if (handlers != null)
{
foreach (NotifyCollectionChangedEventHandler handler in
handlers.GetInvocationList())
{
if (handler.Target is CollectionView)
((CollectionView)handler.Target).Refresh();
else
handler(this, e);
}
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_SuppressNotification)
{
base.OnCollectionChanged(e);
if (CollectionChanged != null)
CollectionChanged.Invoke(this, e);
}
}
public void AddRange(IEnumerable<T> list)
{
if (list == null)
throw new ArgumentNullException("list");
_SuppressNotification = true;
foreach (T item in list)
{
Add(item);
}
_SuppressNotification = false;
OnCollectionChangedMultiItem(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list));
}
}
更新:绑定的ListBox我看到一个InvalidOperationException太后(同样的消息你看到的)。根据本<一href=\"http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/listcollectionviewcollectionview-doesnt-support-notifycollectionchanged-with-multiple-items.aspx\"相对=nofollow>文章,那是因为的CollectionView不支持范围的行动。幸运的是,文章还提供了一个解决方案(虽然感觉有点黑客十岁上下)。
UPDATE: After binding to ListBox I was seeing an InvalidOperationException too (same message you were seeing). According to this article that's because CollectionView doesn't support range actions. Luckily the article also supplies a solution (although it feels a little "hack-ish").
更新2:增加引发的重写实施OnCollectionChanged的覆盖CollectionChanged事件(修复)
UPDATE 2: Added a fix that raises the overridden CollectionChanged event in the overridden implementation of OnCollectionChanged().
这篇关于的ObservableCollection:调用OnCollectionChanged有多个新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!