對於批量插入不斷更新UI每一個變化可能(除非你需要實時更新)。除非您有充足的理由保留OCAux
,否則我會將OCMain
定製的收集與自定義IObservableCollection
實施推遲一批完成後的通知。它可以通過兩種方式完成:
1)最簡單的方法是在禁用通知的地方添加一個BeginUpdate()
方法。當您完成收藏工作後,您可以使用EndUpdate()
重新啓用通知。概念一類的證明,從ObservableCollection<T>
繼承:
public void BeginUpdate() {
_disableNotifications = true;
}
public void EndUpdate() {
_disableNotifications = false;
if (_changed) {
OnCollectionChanged(
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
_changed = false;
}
}
protected override OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
if (_disableNotifications)
_changed = true;
else
base.OnCollectionChanged(e);
}
只是適用同樣的邏輯也爲INotifyPropertyChanged
接口籌集事件PropertyChanged
爲Count
和Items
性能。
2)第二個選項稍微複雜一些,但即使您不知道批量操作何時開始和結束,它也可以工作。首先讓我們做一個假設:用戶不會注意到更新是否延遲了100毫秒。在這種情況下,我們可以做的是忽略的變化,並在NotificationDelay
毫秒後發送一個NotifyCollectionChangedAction.Reset
。不管你有多少更新,只有一個將在第一個NotificationDelay
毫秒之後發送。概念驗證:
protected override OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
// Another event already queued a delayed notification
if (_isTimerRunning)
return;
// Assuming _timer is a System.Timers.Timer object already configured
// and OnTimerElapsed method attached to its Elapsed event. Note that
// you may also use System.Threading.Timer, pick the proper one
// according to MSDN and your requirements
_isTimerRunning = true;
_timer.Start();
}
private void OnTimerElapsed(Object source, ElapsedEventArgs e) {
_isTimerRunning = false;
_timer.Stop();
base.OnCollectionChanged(
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
再次,您必須爲INotifyPropertyChanged
實施做類似的事情。
請注意,在這兩種情況下,我們會丟棄一些信息,因爲CollectionChanged
不會觸發,例如,NotifyCollectionChangedAction.Add
但僅與NotifyCollectionChangedAction.Reset
發生衝突。無論如何,如果它只是用於綁定,那麼你對INotifyPropertyChanged
通知更感興趣,這應該不成問題。
添加到OCAux。然後訂購它。使用OCAux.indexOf(item)獲取添加項目的索引。然後將其插入OCMain。 OCMain.Insert(索引,項);那是你想要的嗎? – Archana
我在CollectionViewSource中進行排序,但我只知道WPF。另一個訣竅是返回一個IEnumerable,並在枚舉上調用NotifyProperty更改,但在所有情況下都不起作用。很確定,ObservableCollection沒有InsertAt。 – Paparazzi