平常需要跟前台界面绑定,并且需要动态插入删除数据项的集合,我们经常会用到ObservableCollection类,这个类本身带通知事件,集合有变化时,能实时通知界面更新。
但是,这个类本身没有批量插入和删除的方法,我们平常需要频率进行一些插入和删除时,界面就会频率刷新,会导致UI界面会卡。
这种使用场景其实比较多,于是自己把这个类继承封装了一下,允许暂停通知事件。
话不多说,直接上代码:
using System; using System.Collections.ObjectModel; using System.Collections.Specialized; namespace CgdataBase { public class CgObservableCollection<T> : ObservableCollection<T>, ISuspendUpdate { private bool updatesEnabled = true; private bool collectionChanged = false; public void ResumeUpdate() { updatesEnabled = true; if (collectionChanged) { collectionChanged = false; OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } public void SuspendUpdate() { updatesEnabled = false; } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (updatesEnabled) { base.OnCollectionChanged(e); } else { collectionChanged = true; } } } public interface ISuspendUpdate { void SuspendUpdate(); void ResumeUpdate(); } public class SuspendUpdateScope : IDisposable { private ISuspendUpdate _parent; public SuspendUpdateScope(ISuspendUpdate parent) { _parent = parent; parent.SuspendUpdate(); } public void Dispose() { _parent.ResumeUpdate(); } } }
具体代码的调用:
public CgObservableCollection<LogInfo> LogItems { get; set; } LogItems = new CgObservableCollection<LogInfo>(); LogItems.Insert(0, new LogInfo("状态更新:" + state.ToString())); if (LogItems.Count > 30) { using (var scope = new SuspendUpdateScope(LogItems)) { while (LogItems.Count > 10) { LogItems.RemoveAt(LogItems.Count - 1); } } }
其它的使用和ObservableCollection一样,需要用到批量的集合操作的时候,可以借助SuspendUpdateScope类,实现批量操作后统一更新。