[英]Which .Net collection for adding multiple objects at once and getting notified?
正在考慮System.Collections.ObjectModel ObservableCollection<T>
類。 這個很奇怪,因為
我這里需要將一批對象添加到集合中,並且偵聽器還將批處理作為通知的一部分。 我是否缺少ObservableCollection的東西? 還有其他符合我要求的課程嗎?
更新:不想自己動手。 我必須建立在添加/刪除/更改等..很多東西。
似乎INotifyCollectionChanged
接口允許在添加多個項目時進行更新,因此我不確定為什么ObservableCollection<T>
沒有AddRange
。 您可以為AddRange
創建擴展方法,但這將為添加的每個項目導致一個事件。 如果那是不可接受的,那么您應該能夠從ObservableCollection<T>
繼承如下:
public class MyObservableCollection<T> : ObservableCollection<T>
{
// matching constructors ...
bool isInAddRange = false;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// intercept this when it gets called inside the AddRange method.
if (!isInAddRange)
base.OnCollectionChanged(e);
}
public void AddRange(IEnumerable<T> items)
{
isInAddRange = true;
foreach (T item in items)
Add(item);
isInAddRange = false;
var e = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
items.ToList());
base.OnCollectionChanged(e);
}
}
好吧,這個想法與fryguybob的想法相同-有點奇怪,ObservableCollection差不多完成了一半。 這個東西的事件args甚至都沒有使用Generics ..讓我使用IList(就是這樣。..
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace MyNamespace
{
public class ObservableCollectionWithBatchUpdates<T> : ObservableCollection<T>
{
public void AddRange(ICollection<T> obNewItems)
{
IList<T> obAddedItems = new List<T>();
foreach (T obItem in obNewItems)
{
Items.Add(obItem);
obAddedItems.Add(obItem);
}
NotifyCollectionChangedEventArgs obEvtArgs = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
obAddedItems as System.Collections.IList);
base.OnCollectionChanged(obEvtArgs);
}
}
}
System.Collections.ObjectModel.Collection<T>
不僅是一個不錯的選擇,而且在幫助文檔中,有一個示例如何覆蓋其各種受保護的方法以獲得通知。 (向下滾動到示例2。)
如果您使用上述任何一種發送添加范圍命令並將observablecolletion綁定到listview的實現,則將收到此討厭的錯誤。
NotSupportedException at System.Windows.Data.ListCollectionView.ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e) at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
我使用的實現使用Reset事件,該事件在WPF框架周圍更均勻地實現:
public void AddRange(IEnumerable<T> collection)
{
foreach (var i in collection) Items.Add(i);
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
我已經多次看到這種問題,而且我想知道為什么連微軟都在其他地方已經推廣了更好的collection的地方推廣ObservableCollection。
BindingList<T>
這使您可以關閉通知並執行批量操作,然后打開通知。
如果要從某種集合中繼承,最好從System.Collections.ObjectModel.Collection繼承,因為它提供了用於重寫的虛擬方法。 如果走那條路線,您將不得不將方法從List中刪除。
我不知道任何提供此功能的內置集合,但我歡迎對此進行糾正:)
類似於CollectionView模式的另一個解決方案:
public class DeferableObservableCollection<T> : ObservableCollection<T>
{
private int deferLevel;
private class DeferHelper<T> : IDisposable
{
private DeferableObservableCollection<T> owningCollection;
public DeferHelper(DeferableObservableCollection<T> owningCollection)
{
this.owningCollection = owningCollection;
}
public void Dispose()
{
owningCollection.EndDefer();
}
}
private void EndDefer()
{
if (--deferLevel <= 0)
{
deferLevel = 0;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
public IDisposable DeferNotifications()
{
deferLevel++;
return new DeferHelper<T>(this);
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (deferLevel == 0) // Not in a defer just send events as normally
{
base.OnCollectionChanged(e);
} // Else notify on EndDefer
}
}
從List <T>繼承並重寫Add()和AddRange()方法引發事件?
看看C#和VB中具有AddRange,RemoveRange和Replace range方法的Observable集合 。
在VB中:INotifyCollectionChanging實現。
為了快速添加,您可以使用:
((List<Person>)this.Items).AddRange(NewItems);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.