class in .NET provides a dynamic collection of data that can be notified when items are added, removed, or rearranged. However, it lacks the ObservableCollection
method, which cannot batch add multiple items at once. Additionally, the AddRange
interface can be used to track changes before they are committed to the collection, providing the opportunity to cancel the changes. INotifyCollectionChanging
method in ObservableCollection
and integrate 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>
events. It also includes an override of the INotifyCollectionChanging
method to ensure that after the custom event is triggered, the base class's OnCollectionChanging
method is still called, thus ensuring the normal functionality of OnCollectionChanging
. ObservableCollection
The above is the detailed content of How to Add an AddRange Method and INotifyCollectionChanging to an ObservableCollection in .NET?. For more information, please follow other related articles on the PHP Chinese website!