.NET中的ObservableCollection
類別提供了一個動態資料集合,可以在新增、刪除或重新排列項目時發出通知。但是,它缺少AddRange
方法,該方法無法一次批量添加多個項目。此外,INotifyCollectionChanging
介面可用於在更改提交到集合之前追蹤更改,從而提供取消更改的機會。
以下是如何在ObservableCollection
中實作AddRange
方法並整合INotifyCollectionChanging
。
C#:
<code class="language-csharp">using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Collections.Specialized; public class ObservableRangeCollection<T> : ObservableCollection<T>, INotifyCollectionChanging<T> { public event NotifyCollectionChangingEventHandler<T> CollectionChanging; protected override void OnCollectionChanging(NotifyCollectionChangingEventArgs e) { // 创建一个包含更改信息的事件参数 var typedEventArgs = new NotifyCollectionChangingEventArgs<T>(e.Action, e.NewItems != null ? (IEnumerable<T>)e.NewItems : null, e.OldItems != null ? (IEnumerable<T>)e.OldItems : null, e.Index); // 触发自定义事件,允许取消操作 CollectionChanging?.Invoke(this, typedEventArgs); // 检查是否取消 if (typedEventArgs.Cancel) { return; } // 调用基类的OnCollectionChanging方法 base.OnCollectionChanging(e); } public void AddRange(IEnumerable<T> collection) { if (collection == null) { throw new ArgumentNullException(nameof(collection)); } // 触发CollectionChanging事件 OnCollectionChanging(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection)); // 添加项目 foreach (T item in collection) { Add(item); } } } //自定义INotifyCollectionChanging接口,用于类型安全 public interface INotifyCollectionChanging<T> : INotifyCollectionChanged { event NotifyCollectionChangingEventHandler<T> CollectionChanging; } //自定义事件处理程序,用于类型安全 public delegate void NotifyCollectionChangingEventHandler<T>(object sender, NotifyCollectionChangingEventArgs<T> e); //自定义事件参数,用于类型安全 public class NotifyCollectionChangingEventArgs<T> : NotifyCollectionChangedEventArgs { public NotifyCollectionChangingEventArgs(NotifyCollectionChangedAction action, IEnumerable<T> newItems) : base(action, newItems) { } public NotifyCollectionChangingEventArgs(NotifyCollectionChangedAction action, IEnumerable<T> newItems, IEnumerable<T> oldItems) : base(action, newItems, oldItems) { } public NotifyCollectionChangingEventArgs(NotifyCollectionChangedAction action, IEnumerable<T> newItems, int index) : base(action, newItems, index) { } public NotifyCollectionChangingEventArgs(NotifyCollectionChangedAction action, T newItem, int index) : base(action, newItem, index) { } public NotifyCollectionChangingEventArgs(NotifyCollectionChangedAction action, T oldItem, int index) : base(action, null, oldItem, index) { } public bool Cancel { get; set; } }</code>
VB.NET:
<code class="language-vb.net">Imports System Imports System.Collections.ObjectModel Imports System.Collections.Generic Imports System.Collections.Specialized Imports System.ComponentModel Public Class ObservableRangeCollection(Of T) Inherits ObservableCollection(Of T) Implements INotifyCollectionChanging(Of T) Public Event CollectionChanging As NotifyCollectionChangingEventHandler(Of T) Implements INotifyCollectionChanging(Of T).CollectionChanging Protected Overrides Sub OnCollectionChanging(e As NotifyCollectionChangedEventArgs) Dim typedEventArgs As New NotifyCollectionChangingEventArgs(Of T)(e.Action, If(e.NewItems IsNot Nothing, DirectCast(e.NewItems, IEnumerable(Of T)), Nothing), If(e.OldItems IsNot Nothing, DirectCast(e.OldItems, IEnumerable(Of T)), Nothing), e.Index) RaiseEvent CollectionChanging(Me, typedEventArgs) If typedEventArgs.Cancel Then Return End If MyBase.OnCollectionChanging(e) End Sub Public Sub AddRange(collection As IEnumerable(Of T)) If collection Is Nothing Then Throw New ArgumentNullException("collection") End If OnCollectionChanging(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection)) For Each item As T In collection Add(item) Next End Sub End Class '自定义INotifyCollectionChanging接口,用于类型安全 Public Interface INotifyCollectionChanging(Of T) Inherits INotifyCollectionChanged Event CollectionChanging As NotifyCollectionChangingEventHandler(Of T) End Interface '自定义事件处理程序,用于类型安全 Public Delegate Sub NotifyCollectionChangingEventHandler(Of T)(sender As Object, e As NotifyCollectionChangingEventArgs(Of T)) '自定义事件参数,用于类型安全 Public Class NotifyCollectionChangingEventArgs(Of T) Inherits NotifyCollectionChangedEventArgs Public Sub New(action As NotifyCollectionChangedAction, newItems As IEnumerable(Of T)) MyBase.New(action, newItems) End Sub Public Sub New(action As NotifyCollectionChangedAction, newItems As IEnumerable(Of T), oldItems As IEnumerable(Of T)) MyBase.New(action, newItems, oldItems) End Sub Public Sub New(action As NotifyCollectionChangedAction, newItems As IEnumerable(Of T), index As Integer) MyBase.New(action, newItems, index) End Sub Public Sub New(action As NotifyCollectionChangedAction, newItem As T, index As Integer) MyBase.New(action, newItem, index) End Sub Public Sub New(action As NotifyCollectionChangedAction, oldItem As T, index As Integer) MyBase.New(action, Nothing, oldItem, index) End Sub Public Property Cancel As Boolean End Class</code>
透過這種方法,您可以在能夠追蹤並在發生之前取消更改的同時,從批次操作中受益。 程式碼已改進,使其更健壯,並處理了 INotifyCollectionChanging
事件的類型安全問題。 它還包含了對 OnCollectionChanging
方法的重寫,以確保在觸發自訂事件後,仍然呼叫基底類別的 OnCollectionChanging
方法,從而保證 ObservableCollection
的正常功能。
以上是如何將 AddRange 方法和 INotifyCollectionChanging 加入 .NET 中的 ObservableCollection?的詳細內容。更多資訊請關注PHP中文網其他相關文章!