using System; using System.Runtime; using System.Runtime.CompilerServices; namespace System.Collections.Specialized { /// Describes the action that caused a event. [__DynamicallyInvokable] public enum NotifyCollectionChangedAction { /// One or more items were added to the collection. Add, /// One or more items were removed from the collection. Remove, /// One or more items were replaced in the collection. Replace, /// One or more items were moved within the collection. Move, /// The content of the collection changed dramatically. Reset } /// Provides data for the event. [__DynamicallyInvokable] public class NotifyCollectionChangedEventArgs : EventArgs { private NotifyCollectionChangedAction _action; private IList _newItems; private IList _oldItems; private int _newStartingIndex = -1; private int _oldStartingIndex = -1; /// Gets the action that caused the event. /// A value that describes the action that caused the event. [__DynamicallyInvokable] public NotifyCollectionChangedAction Action { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this._action; } } /// Gets the list of new items involved in the change. /// The list of new items involved in the change. [__DynamicallyInvokable] public IList NewItems { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this._newItems; } } /// Gets the list of items affected by a , Remove, or Move action. /// The list of items affected by a , Remove, or Move action. [__DynamicallyInvokable] public IList OldItems { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this._oldItems; } } /// Gets the index at which the change occurred. /// The zero-based index at which the change occurred. [__DynamicallyInvokable] public int NewStartingIndex { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this._newStartingIndex; } } /// Gets the index at which a , Remove, or Replace action occurred. /// The zero-based index at which a , Remove, or Replace action occurred. [__DynamicallyInvokable] public int OldStartingIndex { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this._oldStartingIndex; } } /// Initializes a new instance of the class that describes a change. /// The action that caused the event. This must be set to . [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action) { if (action != NotifyCollectionChangedAction.Reset) { throw new ArgumentException("WrongActionForCtor"); } this.InitializeAdd(action, null, -1); } /// Initializes a new instance of the class that describes a one-item change. /// The action that caused the event. This can be set to , , or . /// The item that is affected by the change. /// If is not Reset, Add, or Remove, or if is Reset and is not null. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem) { if (action != NotifyCollectionChangedAction.Add && action != NotifyCollectionChangedAction.Remove && action != NotifyCollectionChangedAction.Reset) { throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); } if (action != NotifyCollectionChangedAction.Reset) { this.InitializeAddOrRemove(action, new object[] { changedItem }, -1); return; } if (changedItem != null) { throw new ArgumentException("ResetActionRequiresNullItem"); } this.InitializeAdd(action, null, -1); } /// Initializes a new instance of the class that describes a one-item change. /// The action that caused the event. This can be set to , , or . /// The item that is affected by the change. /// The index where the change occurred. /// If is not Reset, Add, or Remove, or if is Reset and either is not null or is not -1. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index) { if (action != NotifyCollectionChangedAction.Add && action != NotifyCollectionChangedAction.Remove && action != NotifyCollectionChangedAction.Reset) { throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); } if (action != NotifyCollectionChangedAction.Reset) { this.InitializeAddOrRemove(action, new object[] { changedItem }, index); return; } if (changedItem != null) { throw new ArgumentException("ResetActionRequiresNullItem"); } if (index != -1) { throw new ArgumentException("ResetActionRequiresIndexMinus1"); } this.InitializeAdd(action, null, -1); } /// Initializes a new instance of the class that describes a multi-item change. /// The action that caused the event. This can be set to , , or . /// The items that are affected by the change. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems) { if (action != NotifyCollectionChangedAction.Add && action != NotifyCollectionChangedAction.Remove && action != NotifyCollectionChangedAction.Reset) { throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); } if (action == NotifyCollectionChangedAction.Reset) { if (changedItems != null) { throw new ArgumentException("ResetActionRequiresNullItem"); } this.InitializeAdd(action, null, -1); return; } else { if (changedItems == null) { throw new ArgumentNullException("changedItems"); } this.InitializeAddOrRemove(action, changedItems, -1); return; } } /// Initializes a new instance of the class that describes a multi-item change or a change. /// The action that caused the event. This can be set to , , or . /// The items affected by the change. /// The index where the change occurred. /// If is not Reset, Add, or Remove, if is Reset and either is not null or is not -1, or if action is Add or Remove and is less than -1. /// If is Add or Remove and is null. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) { if (action != NotifyCollectionChangedAction.Add && action != NotifyCollectionChangedAction.Remove && action != NotifyCollectionChangedAction.Reset) { throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor"); } if (action == NotifyCollectionChangedAction.Reset) { if (changedItems != null) { throw new ArgumentException("ResetActionRequiresNullItem"); } if (startingIndex != -1) { throw new ArgumentException("ResetActionRequiresIndexMinus1"); } this.InitializeAdd(action, null, -1); return; } else { if (changedItems == null) { throw new ArgumentNullException("changedItems"); } if (startingIndex < -1) { throw new ArgumentException("IndexCannotBeNegative"); } this.InitializeAddOrRemove(action, changedItems, startingIndex); return; } } /// Initializes a new instance of the class that describes a one-item change. /// The action that caused the event. This can only be set to . /// The new item that is replacing the original item. /// The original item that is replaced. /// If is not Replace. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem) { if (action != NotifyCollectionChangedAction.Replace) { throw new ArgumentException("WrongActionForCtor"); } this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1); } /// Initializes a new instance of the class that describes a one-item change. /// The action that caused the event. This can be set to . /// The new item that is replacing the original item. /// The original item that is replaced. /// The index of the item being replaced. /// If is not Replace. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index) { if (action != NotifyCollectionChangedAction.Replace) { throw new ArgumentException("WrongActionForCtor"); } this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index); } /// Initializes a new instance of the class that describes a multi-item change. /// The action that caused the event. This can only be set to . /// The new items that are replacing the original items. /// The original items that are replaced. /// If is not Replace. /// If or is null. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems) { if (action != NotifyCollectionChangedAction.Replace) { throw new ArgumentException("WrongActionForCtor"); } if (newItems == null) { throw new ArgumentNullException("newItems"); } if (oldItems == null) { throw new ArgumentNullException("oldItems"); } this.InitializeMoveOrReplace(action, newItems, oldItems, -1, -1); } /// Initializes a new instance of the class that describes a multi-item change. /// The action that caused the event. This can only be set to . /// The new items that are replacing the original items. /// The original items that are replaced. /// The index of the first item of the items that are being replaced. /// If is not Replace. /// If or is null. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) { if (action != NotifyCollectionChangedAction.Replace) { throw new ArgumentException("WrongActionForCtor"); } if (newItems == null) { throw new ArgumentNullException("newItems"); } if (oldItems == null) { throw new ArgumentNullException("oldItems"); } this.InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex); } /// Initializes a new instance of the class that describes a one-item change. /// The action that caused the event. This can only be set to . /// The item affected by the change. /// The new index for the changed item. /// The old index for the changed item. /// If is not Move or is less than 0. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) { if (action != NotifyCollectionChangedAction.Move) { throw new ArgumentException("WrongActionForCtor"); } if (index < 0) { throw new ArgumentException("IndexCannotBeNegative"); } object[] array = new object[] { changedItem }; this.InitializeMoveOrReplace(action, array, array, index, oldIndex); } /// Initializes a new instance of the class that describes a multi-item change. /// The action that caused the event. This can only be set to . /// The items affected by the change. /// The new index for the changed items. /// The old index for the changed items. /// If is not Move or is less than 0. [__DynamicallyInvokable] public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) { if (action != NotifyCollectionChangedAction.Move) { throw new ArgumentException("WrongActionForCtor"); } if (index < 0) { throw new ArgumentException("IndexCannotBeNegative"); } this.InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); } internal NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int newIndex, int oldIndex) { this._action = action; this._newItems = ((newItems == null) ? null : ArrayList.ReadOnly(newItems)); this._oldItems = ((oldItems == null) ? null : ArrayList.ReadOnly(oldItems)); this._newStartingIndex = newIndex; this._oldStartingIndex = oldIndex; } private void InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex) { if (action == NotifyCollectionChangedAction.Add) { this.InitializeAdd(action, changedItems, startingIndex); return; } if (action == NotifyCollectionChangedAction.Remove) { this.InitializeRemove(action, changedItems, startingIndex); } } private void InitializeAdd(NotifyCollectionChangedAction action, IList newItems, int newStartingIndex) { this._action = action; this._newItems = ((newItems == null) ? null : ArrayList.ReadOnly(newItems)); this._newStartingIndex = newStartingIndex; } private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex) { this._action = action; this._oldItems = ((oldItems == null) ? null : ArrayList.ReadOnly(oldItems)); this._oldStartingIndex = oldStartingIndex; } private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex) { this.InitializeAdd(action, newItems, startingIndex); this.InitializeRemove(action, oldItems, oldStartingIndex); } } /// Represents the method that handles the event. /// The object that raised the event. /// Information about the event. [__DynamicallyInvokable] public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e); /// Notifies listeners of dynamic changes, such as when items get added and removed or the whole list is refreshed. [__DynamicallyInvokable] public interface INotifyCollectionChanged { /// Occurs when the collection changes. [__DynamicallyInvokable] event NotifyCollectionChangedEventHandler CollectionChanged; } }