diff --git a/Source/Collections/ObservableCollection.Test.cs b/Source/Collections/ObservableCollection.Test.cs
index 41aa18b..ec5095e 100644
--- a/Source/Collections/ObservableCollection.Test.cs
+++ b/Source/Collections/ObservableCollection.Test.cs
@@ -117,30 +117,6 @@ namespace Nuclex.Support.Collections {
this.mockery.VerifyAllExpectationsHaveBeenMet();
}
- /// Tests whether items in the collection can be replaced
- [Test]
- public void TestItemReplacement() {
- this.mockedSubscriber.Expects.Exactly(3).Method(
- m => m.ItemAdded(null, null)
- ).WithAnyArguments();
-
- this.observedCollection.Add(1);
- this.observedCollection.Add(2);
- this.observedCollection.Add(3);
-
- this.mockedSubscriber.Expects.One.Method(m => m.ItemRemoved(null, null)).WithAnyArguments();
- this.mockedSubscriber.Expects.One.Method(m => m.ItemAdded(null, null)).WithAnyArguments();
-
- // Replace the middle item with something else
- this.observedCollection[1] = 4;
-
- Assert.AreEqual(
- 1, this.observedCollection.IndexOf(4)
- );
-
- this.mockery.VerifyAllExpectationsHaveBeenMet();
- }
-
/// Tests whether a the list constructor is working
[Test]
public void TestListConstructor() {
diff --git a/Source/Collections/ObservableCollection.cs b/Source/Collections/ObservableCollection.cs
index 89f5fc1..0ae0342 100644
--- a/Source/Collections/ObservableCollection.cs
+++ b/Source/Collections/ObservableCollection.cs
@@ -19,6 +19,7 @@ License along with this library
#endregion
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
#if !NO_SPECIALIZED_COLLECTIONS
@@ -30,7 +31,8 @@ namespace Nuclex.Support.Collections {
/// Collection which fires events when items are added or removed
/// Type of items the collection manages
public class ObservableCollection :
- Collection,
+ ICollection,
+ ICollection,
#if !NO_SPECIALIZED_COLLECTIONS
INotifyCollectionChanged,
#endif
@@ -55,87 +57,98 @@ namespace Nuclex.Support.Collections {
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endif
- ///
- /// Initializes a new instance of the ObservableCollection class that is empty.
- ///
- public ObservableCollection() : base() { }
+ /// Initializes a new ObservableCollection with no items
+ public ObservableCollection() : this(new Collection()) {}
///
- /// Initializes a new instance of the ObservableCollection class as a wrapper
- /// for the specified list.
+ /// Initializes a new ObservableCollection as a wrapper for an existing collection
///
- /// The list that is wrapped by the new collection.
+ /// Collection that will be wrapped
/// List is null
- public ObservableCollection(IList list) : base(list) { }
+ public ObservableCollection(ICollection collection) {
+ this.typedCollection = collection;
+ this.objectCollection = (collection as ICollection);
+ }
/// Removes all elements from the Collection
- protected override void ClearItems() {
+ public void Clear() {
OnClearing();
- base.ClearItems();
+ this.typedCollection.Clear();
OnCleared();
#if !NO_SPECIALIZED_COLLECTIONS
- OnCollectionChanged(NotifyCollectionChangedAction.Reset, default(TItem), -1);
+ if(CollectionChanged != null) {
+ CollectionChanged(this, CollectionResetEventArgs);
+ }
#endif
}
+ /// Adds an item to the collection
+ /// Collection an item will be added to
+ public void Add(TItem item) {
+ this.typedCollection.Add(item);
+ OnAdded(item);
#if !NO_SPECIALIZED_COLLECTIONS
- /// Fires the CollectionChanged event
- /// Type of change that has occured
- /// The item that has been added, removed or replaced
- /// Index of the changed item
- protected virtual void OnCollectionChanged(
- NotifyCollectionChangedAction action, TItem item, int index
- ) {
if(CollectionChanged != null) {
CollectionChanged(
- this, new NotifyCollectionChangedEventArgs(action, item, index)
- );
+ this,
+ new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)
+ );
}
- }
#endif
+ }
- ///
- /// Inserts an element into the ObservableCollection at the specified index
- ///
- ///
- /// The object to insert. The value can be null for reference types.
+ /// Determines whether the collection contains the specified item
+ /// Item the collection will be searched for
+ ///
+ /// True if the collection contains the specified item, false otherwise
+ ///
+ public bool Contains(TItem item) {
+ return this.typedCollection.Contains(item);
+ }
+
+ /// Copies the contents of the collection into an array
+ /// Array the collection's contents will be copied into
+ ///
+ /// Index in the array where the collection's first item will be placed
///
- /// The zero-based index at which item should be inserted
- protected override void InsertItem(int index, TItem item) {
- base.InsertItem(index, item);
- OnAdded(item);
-#if !NO_SPECIALIZED_COLLECTIONS
- OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
-#endif
+ public void CopyTo(TItem[] array, int arrayIndex) {
+ this.typedCollection.CopyTo(array, arrayIndex);
}
- ///
- /// Removes the element at the specified index of the ObservableCollection
- ///
- /// The zero-based index of the element to remove
- protected override void RemoveItem(int index) {
- TItem item = base[index];
- base.RemoveItem(index);
- OnRemoved(item);
-#if !NO_SPECIALIZED_COLLECTIONS
- OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index);
-#endif
+ /// The total number of items currently in the collection
+ public int Count {
+ get { return this.typedCollection.Count; }
}
- /// Replaces the element at the specified index
- ///
- /// The new value for the element at the specified index. The value can be null
- /// for reference types
- ///
- /// The zero-based index of the element to replace
- protected override void SetItem(int index, TItem item) {
- TItem oldItem = base[index];
- base.SetItem(index, item);
- OnRemoved(oldItem);
- OnAdded(item);
+ /// Whether the collection is read-only
+ public bool IsReadOnly {
+ get { return this.typedCollection.IsReadOnly; }
+ }
+
+ /// Removes an item from the collection
+ /// Item that will be removed from the collection
+ /// True if the item was found and removed, false otherwise
+ public bool Remove(TItem item) {
+ bool wasRemoved = this.typedCollection.Remove(item);
+ if(wasRemoved) {
+ OnRemoved(item);
#if !NO_SPECIALIZED_COLLECTIONS
- OnCollectionChanged(NotifyCollectionChangedAction.Replace, item, index);
+ if(CollectionChanged != null) {
+ CollectionChanged(
+ this,
+ new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)
+ );
+ }
#endif
+ }
+
+ return wasRemoved;
+ }
+
+ /// Returns an enumerator for the items in the collection
+ /// An enumeration for the items in the collection
+ public IEnumerator GetEnumerator() {
+ return this.typedCollection.GetEnumerator();
}
/// Fires the 'ItemAdded' event
@@ -164,6 +177,52 @@ namespace Nuclex.Support.Collections {
Cleared(this, EventArgs.Empty);
}
+ #region IEnumerable implementation
+
+ /// Returns an enumerator for the items in the collection
+ /// An enumeration for the items in the collection
+ IEnumerator IEnumerable.GetEnumerator() {
+ return this.objectCollection.GetEnumerator();
+ }
+
+ #endregion // IEnumerable implementation
+
+ #region ICollection implementation
+
+ /// Copies the contents of the collection into an array
+ /// Array the collection's contents will be copied into
+ ///
+ /// Index in the array where the collection's first item will be placed
+ ///
+ void ICollection.CopyTo(Array array, int arrayIndex) {
+ this.objectCollection.CopyTo(array, arrayIndex);
+ }
+
+ /// Whether the collection synchronizes accesses from multiple threads
+ bool ICollection.IsSynchronized {
+ get { return this.objectCollection.IsSynchronized; }
+ }
+
+ ///
+ /// Synchronization root used to synchronize threads accessing the collection
+ ///
+ object ICollection.SyncRoot {
+ get { return this.objectCollection.SyncRoot; }
+ }
+
+ #endregion // IEnumerable implementation
+
+#if !NO_SPECIALIZED_COLLECTIONS
+ /// Fixed event args used to notify that the collection has reset
+ private static readonly NotifyCollectionChangedEventArgs CollectionResetEventArgs =
+ new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
+#endif
+
+ /// The wrapped collection under its type-safe interface
+ private ICollection typedCollection;
+ /// The wrapped collection under its object interface
+ private ICollection objectCollection;
+
}
} // namespace Nuclex.Support.Collections
diff --git a/Source/Collections/ObservableList.cs b/Source/Collections/ObservableList.cs
index f6ce57c..710c15f 100644
--- a/Source/Collections/ObservableList.cs
+++ b/Source/Collections/ObservableList.cs
@@ -364,9 +364,9 @@ namespace Nuclex.Support.Collections {
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
#endif
- /// The wrapped List under its type-safe interface
+ /// The wrapped list under its type-safe interface
private IList typedList;
- /// The wrapped List under its object interface
+ /// The wrapped list under its object interface
private IList objectList;
}