using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace DevComponents.DotNetBar.Primitives
{
///
/// Represents custom collection with INotifyPropertyChanged and INotifyCollectionChanged interface support.
///
///
[Serializable, DebuggerDisplay("Count = {Count}"), ComVisible(false)]
public class CustomCollection : IList, IList, INotifyPropertyChanged, INotifyCollectionChanged
{
#region Events
///
/// Occurs when property value has changed.
///
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Private variables
private SimpleMonitor _monitor;
private object _SyncRoot;
private readonly IList _Items;
private bool _FloatLastItem;
#endregion
#region Constructors
///
/// Creates new instance of object.
///
public CustomCollection()
{
_monitor = new SimpleMonitor();
_Items = new List();
}
public void Dispose()
{
_monitor.Dispose();
}
///
/// Creates new instance of object.
///
public CustomCollection(int capacity)
{
_monitor = new SimpleMonitor();
_Items = new List(capacity);
}
///
/// Creates new instance of object.
///
/// List to initialize collection with.
public CustomCollection(IList list)
{
if (list == null)
throw new ArgumentNullException("list");
_monitor = new SimpleMonitor();
_Items = list;
}
#endregion
#region Add
///
/// Add item to collection.
///
/// Item to add.
public void Add(T item)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
InsertItem(_Items.Count, item);
}
#endregion
#region Sort
//
// Summary:
// Sorts the elements in the entire collection using
// the default comparer.
//
// Exceptions:
// System.InvalidOperationException:
// The default comparer System.Collections.Generic.Comparer.Default cannot
// find an implementation of the System.IComparable generic interface or
// the System.IComparable interface for type T.
public void Sort()
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if(!(_Items is List))
throw new NotSupportedException("collection must be default List collection");
((List)_Items).Sort();
OnCollectionChanged(NotifyCollectionChangedAction.Reset, null, -1);
}
//
// Summary:
// Reverse sorts the elements in the entire collection.
//
public void SortReverse()
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if (!(_Items is List))
throw new NotSupportedException("collection must be default List collection");
((List)_Items).Sort();
((List)_Items).Reverse();
OnCollectionChanged(NotifyCollectionChangedAction.Reset, null, -1);
}
//
// Summary:
// Sorts the elements in the entire collection using
// the specified System.Comparison.
//
// Parameters:
// comparison:
// The System.Comparison to use when comparing elements.
//
// Exceptions:
// System.ArgumentNullException:
// comparison is null.
//
// System.ArgumentException:
// The implementation of comparison caused an error during the sort. For example,
// comparison might not return 0 when comparing an item with itself.
public void Sort(Comparison comparison)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if (!(_Items is List))
throw new NotSupportedException("collection must be default List collection");
((List)_Items).Sort(comparison);
OnCollectionChanged(NotifyCollectionChangedAction.Reset, null, -1);
}
//
// Summary:
// Sorts the elements in the entire System.Collections.Generic.List using
// the specified comparer.
//
// Parameters:
// comparer:
// The System.Collections.Generic.IComparer implementation to use when comparing
// elements, or null to use the default comparer System.Collections.Generic.Comparer.Default.
//
// Exceptions:
// System.InvalidOperationException:
// comparer is null, and the default comparer System.Collections.Generic.Comparer.Default
// cannot find implementation of the System.IComparable generic interface
// or the System.IComparable interface for type T.
//
// System.ArgumentException:
// The implementation of comparer caused an error during the sort. For example,
// comparer might not return 0 when comparing an item with itself.
public void Sort(IComparer comparer)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if (!(_Items is List))
throw new NotSupportedException("collection must be default List collection");
((List)_Items).Sort(comparer);
OnCollectionChanged(NotifyCollectionChangedAction.Reset, null, -1);
}
//
// Summary:
// Sorts the elements in a range of elements in System.Collections.Generic.List
// using the specified comparer.
//
// Parameters:
// index:
// The zero-based starting index of the range to sort.
//
// count:
// The length of the range to sort.
//
// comparer:
// The System.Collections.Generic.IComparer implementation to use when comparing
// elements, or null to use the default comparer System.Collections.Generic.Comparer.Default.
//
// Exceptions:
// System.ArgumentOutOfRangeException:
// index is less than 0.-or-count is less than 0.
//
// System.ArgumentException:
// index and count do not specify a valid range in the System.Collections.Generic.List.-or-The
// implementation of comparer caused an error during the sort. For example,
// comparer might not return 0 when comparing an item with itself.
//
// System.InvalidOperationException:
// comparer is null, and the default comparer System.Collections.Generic.Comparer.Default
// cannot find implementation of the System.IComparable generic interface
// or the System.IComparable interface for type T.
public void Sort(int index, int count, IComparer comparer)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if (!(_Items is List))
throw new NotSupportedException("collection must be default List collection");
((List)_Items).Sort(index, count, comparer);
OnCollectionChanged(NotifyCollectionChangedAction.Reset, null, -1);
}
#endregion
#region Clear
///
/// Remove all items from collection.
///
public void Clear()
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
ClearItems();
}
///
/// Remove all items from collection.
///
protected virtual void ClearItems()
{
CheckReentrancy();
T item = default(T);
if (_FloatLastItem == true)
{
if (_Items.Count > 0)
item = _Items[_Items.Count - 1];
}
_Items.Clear();
OnPropertyChanged(new PropertyChangedEventArgs(CountString));
OnPropertyChanged(new PropertyChangedEventArgs(ItemString));
OnCollectionReset();
if (_FloatLastItem == true)
_Items.Add(item);
}
#endregion
#region Contains
///
/// Checks whether collection contains item.
///
/// Item to look for.
/// true if item is in collection.
public bool Contains(T item)
{
OnCollectionReadAccess();
return (_Items.Contains(item));
}
#endregion
#region CopyTo
///
/// Copy collection to array.
///
/// Array to copy to.
/// Index to copy from.
public void CopyTo(T[] array, int index)
{
OnCollectionReadAccess();
_Items.CopyTo(array, index);
}
///
/// Copy collection to array.
///
/// Array to copy to.
public void CopyTo(T[] array)
{
CopyTo(array, 0);
}
#endregion
#region Count
///
/// Returns number of items in collection.
///
public int Count
{
get
{
OnCollectionReadAccess();
return (_Items.Count);
}
}
#endregion
#region CountString
private string CountString
{
get { return ("Count"); }
}
#endregion
#region FloatLastItem
internal bool FloatLastItem
{
get { return (_FloatLastItem); }
set { _FloatLastItem = value; }
}
#endregion
#region GetEnumerator
///
/// Gets enumerator for collection.
///
/// Enumerator.
public IEnumerator GetEnumerator()
{
OnCollectionReadAccess();
return (_Items.GetEnumerator());
}
#endregion
#region Indexer[int]
///
/// Returns item at index.
///
/// Index of item.
/// Item at index.
public T this[int index]
{
get
{
OnCollectionReadAccess();
return (_Items[index]);
}
set
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if ((index < 0) || (index >= _Items.Count))
throw new ArgumentOutOfRangeException();
SetItem(index, value);
}
}
#endregion
#region IndexOf
///
/// Returns index of an item.
///
/// Reference to item.
/// Index of item.
public int IndexOf(T item)
{
OnCollectionReadAccess();
return (_Items.IndexOf(item));
}
#endregion
#region Insert
///
/// Insert item at specified location.
///
/// Index to insert item in.
/// Item to insert.
public void Insert(int index, T item)
{
if ((index < 0) || (index > this._Items.Count))
throw new ArgumentOutOfRangeException("index");
InsertItem(index, item);
}
#endregion
#region InsertItem
///
/// Inserts item.
///
/// Index to insert item at.
/// Reference to item.
protected virtual void InsertItem(int index, T item)
{
CheckReentrancy();
if (_FloatLastItem == true)
{
if (_Items.Count > 0 && index == _Items.Count)
index--;
}
_Items.Insert(index, item);
OnPropertyChanged(new PropertyChangedEventArgs(CountString));
OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
}
#endregion
#region IsCompatibleObject
private static bool IsCompatibleObject(object value)
{
return (value is T) || (value == null && !typeof(T).IsValueType);
}
#endregion
#region ItemString
private string ItemString
{
get { return ("Item[]"); }
}
#endregion
#region Remove
///
/// Removes item from collection.
///
/// Item to remove.
/// true if item was removed.
public bool Remove(T item)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
int index = _Items.IndexOf(item);
if (index < 0)
return (false);
RemoveItem(index);
return (true);
}
#endregion
#region RemoveAt
///
/// Remove item at specified location.
///
/// Index of item to remove.
public void RemoveAt(int index)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if ((index < 0) || (index >= _Items.Count))
throw new ArgumentOutOfRangeException();
RemoveItem(index);
}
#endregion
#region RemoveItem
///
/// Remove item at specified location.
///
/// Index of item to remove.
protected virtual void RemoveItem(int index)
{
CheckReentrancy();
object item = _Items[index];
_Items.RemoveAt(index);
OnPropertyChanged(new PropertyChangedEventArgs(CountString));
OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index);
}
#endregion
#region SetItem
///
/// Set item on location.
///
/// Index
/// Item to assign.
protected virtual void SetItem(int index, T item)
{
CheckReentrancy();
T oldItem = _Items[index];
_Items[index] = item;
OnPropertyChanged(new PropertyChangedEventArgs(CountString));
OnPropertyChanged(new PropertyChangedEventArgs(ItemString));
OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, item, index);
}
#endregion
#region IList support
#region Add
int IList.Add(object value)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
VerifyValueType(value);
Add((T)value);
return (Count - 1);
}
#endregion
#region Contains
bool IList.Contains(object value)
{
return (IsCompatibleObject(value) && Contains((T)value));
}
#endregion
#region GetItemsDirect
///
/// Returns items directly without checks.
///
/// List of items.
protected IList GetItemsDirect()
{
return (_Items);
}
#endregion
#region Indexer[int]
object IList.this[int index]
{
get
{
OnCollectionReadAccess();
return this._Items[index];
}
set
{
VerifyValueType(value);
this[index] = (T)value;
}
}
#region IndexOf
int IList.IndexOf(object value)
{
OnCollectionReadAccess();
return (IsCompatibleObject(value) ? IndexOf((T)value) : -1);
}
#endregion
#region Insert
void IList.Insert(int index, object value)
{
if (this._Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
VerifyValueType(value);
Insert(index, (T)value);
}
#endregion
#region IsFixedSize
bool IList.IsFixedSize
{
get
{
IList items = _Items as IList;
return ((items != null) && items.IsFixedSize);
}
}
#endregion
#region IsReadOnly
bool IList.IsReadOnly
{
get { return (_Items.IsReadOnly); }
}
#endregion
#region Items
///
/// Returns the IList interface for items in collection.
///
protected IList Items
{
get
{
OnCollectionReadAccess();
return (_Items);
}
}
#endregion
#region Remove
void IList.Remove(object value)
{
if (_Items.IsReadOnly)
throw new NotSupportedException("collection is read-only");
if (IsCompatibleObject(value))
Remove((T)value);
}
#endregion
#endregion
#region VerifyValueType
private static void VerifyValueType(object value)
{
if (!IsCompatibleObject(value))
throw new ArgumentException("value is of wrong type");
}
#endregion
#endregion
#region IEnumerable.GetEnumerator
IEnumerator IEnumerable.GetEnumerator()
{
OnCollectionReadAccess();
return (_Items.GetEnumerator());
}
#endregion
#region ICollection support
#region CopyTo
void ICollection.CopyTo(Array array, int index)
{
CheckReentrancy();
OnCollectionReadAccess();
if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Argument array.Rank multi-dimensional not supported");
if (array.GetLowerBound(0) != 0)
throw new ArgumentException("Argument array non zero lower bound not supported");
if (index < 0)
throw new ArgumentOutOfRangeException("index", "index must be non-negative number");
if ((array.Length - index) < this.Count)
throw new ArgumentException("array too small");
T[] localArray = array as T[];
if (localArray != null)
{
_Items.CopyTo(localArray, index);
}
else
{
Type elementType = array.GetType().GetElementType();
Type c = typeof(T);
if (elementType == null ||
(!elementType.IsAssignableFrom(c) && !c.IsAssignableFrom(elementType)))
{
throw new ArgumentException("Argument array of invalid type");
}
object[] objArray = array as object[];
if (objArray == null)
throw new ArgumentException("Argument array invalid type");
int count = this._Items.Count;
try
{
for (int i = 0; i < count; i++)
objArray[index++] = this._Items[i];
}
catch (ArrayTypeMismatchException)
{
throw new ArgumentException("Argument array invalid type");
}
}
}
#endregion
#region IsSynchronized
bool ICollection.IsSynchronized
{
get { return false; }
}
#endregion
#region IsReadOnly
bool ICollection.IsReadOnly
{
get { return this._Items.IsReadOnly; }
}
#endregion
#region SyncRoot
object ICollection.SyncRoot
{
get
{
if (_SyncRoot == null)
{
ICollection items = _Items as ICollection;
if (items != null)
_SyncRoot = items.SyncRoot;
else
System.Threading.Interlocked.CompareExchange(ref _SyncRoot, new object(), null);
}
return (_SyncRoot);
}
}
#endregion
#endregion
#region OnCollectionReadAccess
///
/// Occurs when collection is read.
///
protected virtual void OnCollectionReadAccess()
{
}
#endregion
#region OnPropertyChanged
///
/// Occurs when collection property has changed.
///
/// Event arguments.
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
#endregion
#region BlockReentrancy
///
/// Blocks the collection reentrancy.
///
/// IDisposable to end re-entrancy
protected IDisposable BlockReentrancy()
{
_monitor.Enter();
return (_monitor);
}
#endregion
#region CheckReentrancy
///
/// Checks whether call creates reentrancy.
///
protected void CheckReentrancy()
{
if ((_monitor.Busy && (CollectionChanged != null)) &&
(CollectionChanged.GetInvocationList().Length > 1))
{
throw new InvalidOperationException("CustomCollectionReentrancyNotAllowed");
}
}
#endregion
#region SimpleMonitor
[Serializable]
private class SimpleMonitor : IDisposable
{
// Fields
private int _BusyCount;
// Methods
public void Dispose()
{
_BusyCount--;
}
public void Enter()
{
_BusyCount++;
}
// Properties
public bool Busy
{
get { return (_BusyCount > 0); }
}
}
#endregion
#region INotifyCollectionChanged Members
///
/// Occurs when collection has changed.
///
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index)
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index));
}
private void OnCollectionReset()
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
///
/// Called when collection has changed.
///
/// Event arguments.
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (this.CollectionChanged != null)
{
using (this.BlockReentrancy())
{
this.CollectionChanged(this, e);
}
}
}
#endregion
}
#region INotifyCollectionChanged
///
/// Represents collection changed notification interface.
///
public interface INotifyCollectionChanged
{
///
/// Occurs when collection changed.
///
event NotifyCollectionChangedEventHandler CollectionChanged;
}
///
/// Defines change actions.
///
public enum NotifyCollectionChangedAction
{
///
/// Items were added.
///
Add,
///
/// Items were removed.
///
Remove,
///
/// Items were replaced.
///
Replace,
///
/// Items were moved.
///
Move,
///
/// Collection was reset.
///
Reset
}
///
/// Defines delegate for collection notification events.
///
/// Event sender.
/// Event arguments.
public delegate void NotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e);
///
/// Defines collection change notification event arguments.
///
public class NotifyCollectionChangedEventArgs : EventArgs
{
#region Private Vars
private NotifyCollectionChangedAction _Action;
private IList _NewItems;
private int _NewStartingIndex;
private IList _OldItems;
private int _OldStartingIndex;
#endregion
///
/// Create new instance of object.
///
/// Action
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (action != NotifyCollectionChangedAction.Reset)
{
throw new ArgumentException("WrongActionForCtor");
}
this.InitializeAdd(action, null, -1);
}
///
/// Creates new instance of object.
///
/// Specifies action.
/// List of changed items.
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
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);
}
else
{
if (changedItems == null)
{
throw new ArgumentNullException("changedItems");
}
this.InitializeAddOrRemove(action, changedItems, -1);
}
}
///
/// Creates new instance of object.
///
/// Specifies action.
/// Item that was changed.
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset))
{
throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor");
}
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItem != null)
{
throw new ArgumentException("ResetActionRequiresNullItem");
}
this.InitializeAdd(action, null, -1);
}
else
{
this.InitializeAddOrRemove(action, new object[] { changedItem }, -1);
}
}
///
/// Creates new instance of object.
///
/// Action.
/// New items in collection.
/// Old items in collection.
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
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);
}
///
/// Creates new instance of object.
///
/// Action.
/// List of changed items.
/// Starting index of change.
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int startingIndex)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
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);
}
else
{
if (changedItems == null)
{
throw new ArgumentNullException("changedItems");
}
if (startingIndex < -1)
{
throw new ArgumentException("IndexCannotBeNegative");
}
this.InitializeAddOrRemove(action, changedItems, startingIndex);
}
}
///
/// Creates new instance of object.
///
/// Action
/// Changed item
/// Index of change
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (((action != NotifyCollectionChangedAction.Add) && (action != NotifyCollectionChangedAction.Remove)) && (action != NotifyCollectionChangedAction.Reset))
{
throw new ArgumentException("MustBeResetAddOrRemoveActionForCtor");
}
if (action == NotifyCollectionChangedAction.Reset)
{
if (changedItem != null)
{
throw new ArgumentException("ResetActionRequiresNullItem");
}
if (index != -1)
{
throw new ArgumentException("ResetActionRequiresIndexMinus1");
}
this.InitializeAdd(action, null, -1);
}
else
{
this.InitializeAddOrRemove(action, new object[] { changedItem }, index);
}
}
///
/// Creates new instance of object.
///
/// Action
/// New item
/// Old item
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (action != NotifyCollectionChangedAction.Replace)
{
throw new ArgumentException("WrongActionForCtor");
}
this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1);
}
///
/// Creates new instance of object.
///
/// Action
/// New items.
/// Removed items.
/// Starting index of change.
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
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);
}
///
/// Creates new instance of object.
///
/// Action
/// Changed items
/// New index
/// Old index
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (action != NotifyCollectionChangedAction.Move)
{
throw new ArgumentException("WrongActionForCtor");
}
if (index < 0)
{
throw new ArgumentException("IndexCannotBeNegative");
}
this.InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex);
}
///
/// Creates new instance of object.
///
/// Action
/// Changed item
/// New index
/// Old index
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (action != NotifyCollectionChangedAction.Move)
{
throw new ArgumentException("WrongActionForCtor");
}
if (index < 0)
{
throw new ArgumentException("IndexCannotBeNegative");
}
object[] newItems = new object[] { changedItem };
this.InitializeMoveOrReplace(action, newItems, newItems, index, oldIndex);
}
///
/// Creates new instance of object.
///
/// Action.
/// New item
/// Old item
/// New index
public NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction action, object newItem, object oldItem, int index)
{
this._NewStartingIndex = -1;
this._OldStartingIndex = -1;
if (action != NotifyCollectionChangedAction.Replace)
{
throw new ArgumentException("WrongActionForCtor");
}
this.InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index);
}
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 InitializeAddOrRemove(NotifyCollectionChangedAction action, IList changedItems, int startingIndex)
{
if (action == NotifyCollectionChangedAction.Add)
{
this.InitializeAdd(action, changedItems, startingIndex);
}
else if (action == NotifyCollectionChangedAction.Remove)
{
this.InitializeRemove(action, changedItems, startingIndex);
}
}
private void InitializeMoveOrReplace(NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex)
{
this.InitializeAdd(action, newItems, startingIndex);
this.InitializeRemove(action, oldItems, oldStartingIndex);
}
private void InitializeRemove(NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex)
{
this._Action = action;
this._OldItems = (oldItems == null) ? null : ArrayList.ReadOnly(oldItems);
this._OldStartingIndex = oldStartingIndex;
}
///
/// Gets the type of the collection change action.
///
public NotifyCollectionChangedAction Action
{
get
{
return this._Action;
}
}
///
/// Gets list of newly added items.
///
public IList NewItems
{
get
{
return this._NewItems;
}
}
///
/// Gets new starting index.
///
public int NewStartingIndex
{
get
{
return this._NewStartingIndex;
}
}
///
/// Gets list of removed items.
///
public IList OldItems
{
get
{
return this._OldItems;
}
}
///
/// Old starting index.
///
public int OldStartingIndex
{
get
{
return this._OldStartingIndex;
}
}
}
#endregion
}