Extended to IObservableCollection interface with an ItemsCleared event so subscribers observing the collection only to trigger 'Changed' events (versus subscribers observing the collection to wire/unwire themselves from the collection's items) can make use of the collection
git-svn-id: file:///srv/devel/repo-conversion/nusu@182 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
d5293d8cb9
commit
655ae7ab10
|
@ -42,6 +42,9 @@ namespace Nuclex.Support.Collections {
|
|||
/// </remarks>
|
||||
event EventHandler Clearing;
|
||||
|
||||
/// <summary>Raised when the collection has been cleared of its items</summary>
|
||||
event EventHandler Cleared;
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Support.Collections
|
||||
|
|
|
@ -42,6 +42,11 @@ namespace Nuclex.Support.Collections {
|
|||
/// <param name="arguments">Not used</param>
|
||||
void Clearing(object sender, EventArgs arguments);
|
||||
|
||||
/// <summary>Called when the collection has been cleared of its contents</summary>
|
||||
/// <param name="sender">Collection that was cleared of its contents</param>
|
||||
/// <param name="arguments">Not used</param>
|
||||
void Cleared(object sender, EventArgs arguments);
|
||||
|
||||
/// <summary>Called when an item is added to the collection</summary>
|
||||
/// <param name="sender">Collection to which an item is being added</param>
|
||||
/// <param name="arguments">Contains the item that is being added</param>
|
||||
|
@ -64,7 +69,10 @@ namespace Nuclex.Support.Collections {
|
|||
this.mockedSubscriber = this.mockery.NewMock<IObservableCollectionSubscriber>();
|
||||
|
||||
this.observedCollection = new ObservableCollection<int>();
|
||||
this.observedCollection.Clearing += new EventHandler(this.mockedSubscriber.Clearing);
|
||||
this.observedCollection.Clearing +=
|
||||
new EventHandler(this.mockedSubscriber.Clearing);
|
||||
this.observedCollection.Cleared +=
|
||||
new EventHandler(this.mockedSubscriber.Cleared);
|
||||
this.observedCollection.ItemAdded +=
|
||||
new EventHandler<ItemEventArgs<int>>(
|
||||
this.mockedSubscriber.ItemAdded
|
||||
|
@ -78,9 +86,8 @@ namespace Nuclex.Support.Collections {
|
|||
/// <summary>Tests whether the Clearing event is fired</summary>
|
||||
[Test]
|
||||
public void TestClearingEvent() {
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("Clearing");
|
||||
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Cleared").WithAnyArguments();
|
||||
this.observedCollection.Clear();
|
||||
|
||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||
|
@ -89,9 +96,7 @@ namespace Nuclex.Support.Collections {
|
|||
/// <summary>Tests whether the ItemAdded event is fired</summary>
|
||||
[Test]
|
||||
public void TestItemAddedEvent() {
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("ItemAdded").
|
||||
WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||
|
||||
this.observedCollection.Add(123);
|
||||
|
||||
|
@ -101,15 +106,11 @@ namespace Nuclex.Support.Collections {
|
|||
/// <summary>Tests whether the ItemRemoved event is fired</summary>
|
||||
[Test]
|
||||
public void TestItemRemovedEvent() {
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("ItemAdded").
|
||||
WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||
|
||||
this.observedCollection.Add(123);
|
||||
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("ItemRemoved").
|
||||
WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("ItemRemoved").WithAnyArguments();
|
||||
|
||||
this.observedCollection.Remove(123);
|
||||
|
||||
|
@ -119,28 +120,20 @@ namespace Nuclex.Support.Collections {
|
|||
/// <summary>Tests whether items in the collection can be replaced</summary>
|
||||
[Test]
|
||||
public void TestItemReplacement() {
|
||||
Expect.Exactly(3).On(this.mockedSubscriber).
|
||||
Method("ItemAdded").
|
||||
WithAnyArguments();
|
||||
Expect.Exactly(3).On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||
|
||||
this.observedCollection.Add(1);
|
||||
this.observedCollection.Add(2);
|
||||
this.observedCollection.Add(3);
|
||||
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("ItemRemoved").
|
||||
WithAnyArguments();
|
||||
|
||||
Expect.Once.On(this.mockedSubscriber).
|
||||
Method("ItemAdded").
|
||||
WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("ItemRemoved").WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||
|
||||
// Replace the middle item with something else
|
||||
this.observedCollection[1] = 4;
|
||||
|
||||
Assert.AreEqual(
|
||||
1,
|
||||
this.observedCollection.IndexOf(4)
|
||||
1, this.observedCollection.IndexOf(4)
|
||||
);
|
||||
|
||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||
|
@ -152,11 +145,8 @@ namespace Nuclex.Support.Collections {
|
|||
int[] integers = new int[] { 12, 34, 56, 78 };
|
||||
|
||||
ObservableCollection<int> testCollection = new ObservableCollection<int>(integers);
|
||||
|
||||
CollectionAssert.AreEqual(
|
||||
integers,
|
||||
testCollection
|
||||
);
|
||||
|
||||
CollectionAssert.AreEqual(integers, testCollection);
|
||||
}
|
||||
|
||||
/// <summary>Mock object factory</summary>
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace Nuclex.Support.Collections {
|
|||
/// to process the clearing of the entire collection as a special operation.
|
||||
/// </remarks>
|
||||
public event EventHandler Clearing;
|
||||
/// <summary>Raised when the collection has been cleared</summary>
|
||||
public event EventHandler Cleared;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ObservableCollection class that is empty.
|
||||
|
@ -58,8 +60,8 @@ namespace Nuclex.Support.Collections {
|
|||
/// <summary>Removes all elements from the Collection</summary>
|
||||
protected override void ClearItems() {
|
||||
OnClearing();
|
||||
|
||||
base.ClearItems();
|
||||
OnCleared();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -71,7 +73,6 @@ namespace Nuclex.Support.Collections {
|
|||
/// <param name="item">The zero-based index at which item should be inserted</param>
|
||||
protected override void InsertItem(int index, ItemType item) {
|
||||
base.InsertItem(index, item);
|
||||
|
||||
OnAdded(item);
|
||||
}
|
||||
|
||||
|
@ -81,9 +82,7 @@ namespace Nuclex.Support.Collections {
|
|||
/// <param name="index">The zero-based index of the element to remove</param>
|
||||
protected override void RemoveItem(int index) {
|
||||
ItemType item = base[index];
|
||||
|
||||
base.RemoveItem(index);
|
||||
|
||||
OnRemoved(item);
|
||||
}
|
||||
|
||||
|
@ -95,9 +94,7 @@ namespace Nuclex.Support.Collections {
|
|||
/// <param name="item">The zero-based index of the element to replace</param>
|
||||
protected override void SetItem(int index, ItemType item) {
|
||||
ItemType oldItem = base[index];
|
||||
|
||||
base.SetItem(index, item);
|
||||
|
||||
OnRemoved(oldItem);
|
||||
OnAdded(item);
|
||||
}
|
||||
|
@ -122,6 +119,12 @@ namespace Nuclex.Support.Collections {
|
|||
Clearing(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>Fires the 'Cleared' event</summary>
|
||||
protected virtual void OnCleared() {
|
||||
if(Cleared != null)
|
||||
Cleared(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Support.Collections
|
||||
|
|
|
@ -45,6 +45,11 @@ namespace Nuclex.Support.Collections {
|
|||
/// <param name="arguments">Not used</param>
|
||||
void Clearing(object sender, EventArgs arguments);
|
||||
|
||||
/// <summary>Called when the dictionary has been clear of its contents</summary>
|
||||
/// <param name="sender">Dictionary that was cleared of its contents</param>
|
||||
/// <param name="arguments">Not used</param>
|
||||
void Cleared(object sender, EventArgs arguments);
|
||||
|
||||
/// <summary>Called when an item is added to the dictionary</summary>
|
||||
/// <param name="sender">Dictionary to which an item is being added</param>
|
||||
/// <param name="arguments">Contains the item that is being added</param>
|
||||
|
@ -72,7 +77,10 @@ namespace Nuclex.Support.Collections {
|
|||
this.observedDictionary.Add(3, "three");
|
||||
this.observedDictionary.Add(42, "forty-two");
|
||||
|
||||
this.observedDictionary.Clearing += new EventHandler(this.mockedSubscriber.Clearing);
|
||||
this.observedDictionary.Clearing +=
|
||||
new EventHandler(this.mockedSubscriber.Clearing);
|
||||
this.observedDictionary.Cleared +=
|
||||
new EventHandler(this.mockedSubscriber.Cleared);
|
||||
this.observedDictionary.ItemAdded +=
|
||||
new EventHandler<ItemEventArgs<KeyValuePair<int, string>>>(
|
||||
this.mockedSubscriber.ItemAdded
|
||||
|
@ -293,6 +301,7 @@ namespace Nuclex.Support.Collections {
|
|||
[Test]
|
||||
public void TestClearViaIDictionary() {
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Cleared").WithAnyArguments();
|
||||
(this.observedDictionary as IDictionary).Clear();
|
||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||
|
||||
|
@ -424,6 +433,7 @@ namespace Nuclex.Support.Collections {
|
|||
[Test]
|
||||
public void TestClearViaGenericICollection() {
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
||||
Expect.Once.On(this.mockedSubscriber).Method("Cleared").WithAnyArguments();
|
||||
(this.observedDictionary as ICollection<KeyValuePair<int, string>>).Clear();
|
||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Nuclex.Support.Collections {
|
|||
[Serializable]
|
||||
public class ObservableDictionary<KeyType, ValueType> :
|
||||
#if !NO_SERIALIZATION
|
||||
ISerializable,
|
||||
ISerializable,
|
||||
IDeserializationCallback,
|
||||
#endif
|
||||
IDictionary<KeyType, ValueType>,
|
||||
|
@ -76,6 +76,8 @@ namespace Nuclex.Support.Collections {
|
|||
public event EventHandler<ItemEventArgs<KeyValuePair<KeyType, ValueType>>> ItemRemoved;
|
||||
/// <summary>Raised when the dictionary is about to be cleared</summary>
|
||||
public event EventHandler Clearing;
|
||||
/// <summary>Raised when the dictionary has been cleared</summary>
|
||||
public event EventHandler Cleared;
|
||||
|
||||
/// <summary>Initializes a new observable dictionary</summary>
|
||||
public ObservableDictionary() : this(new Dictionary<KeyType, ValueType>()) { }
|
||||
|
@ -220,6 +222,7 @@ namespace Nuclex.Support.Collections {
|
|||
public void Clear() {
|
||||
OnClearing();
|
||||
this.typedDictionary.Clear();
|
||||
OnCleared();
|
||||
}
|
||||
|
||||
/// <summary>Fires the 'ItemAdded' event</summary>
|
||||
|
@ -242,6 +245,12 @@ namespace Nuclex.Support.Collections {
|
|||
Clearing(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>Fires the 'Cleared' event</summary>
|
||||
protected virtual void OnCleared() {
|
||||
if(Cleared != null)
|
||||
Cleared(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#region IEnumerable implementation
|
||||
|
||||
/// <summary>Returns a new object enumerator for the Dictionary</summary>
|
||||
|
@ -337,6 +346,7 @@ namespace Nuclex.Support.Collections {
|
|||
void ICollection<KeyValuePair<KeyType, ValueType>>.Clear() {
|
||||
OnClearing();
|
||||
this.typedDictionary.Clear();
|
||||
OnCleared();
|
||||
}
|
||||
|
||||
/// <summary>Removes all items from the Dictionary</summary>
|
||||
|
|
Loading…
Reference in New Issue
Block a user