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>
|
/// </remarks>
|
||||||
event EventHandler Clearing;
|
event EventHandler Clearing;
|
||||||
|
|
||||||
|
/// <summary>Raised when the collection has been cleared of its items</summary>
|
||||||
|
event EventHandler Cleared;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Collections
|
} // namespace Nuclex.Support.Collections
|
||||||
|
|
|
@ -42,6 +42,11 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <param name="arguments">Not used</param>
|
/// <param name="arguments">Not used</param>
|
||||||
void Clearing(object sender, EventArgs arguments);
|
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>
|
/// <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="sender">Collection to which an item is being added</param>
|
||||||
/// <param name="arguments">Contains the item that 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.mockedSubscriber = this.mockery.NewMock<IObservableCollectionSubscriber>();
|
||||||
|
|
||||||
this.observedCollection = new ObservableCollection<int>();
|
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 +=
|
this.observedCollection.ItemAdded +=
|
||||||
new EventHandler<ItemEventArgs<int>>(
|
new EventHandler<ItemEventArgs<int>>(
|
||||||
this.mockedSubscriber.ItemAdded
|
this.mockedSubscriber.ItemAdded
|
||||||
|
@ -78,9 +86,8 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <summary>Tests whether the Clearing event is fired</summary>
|
/// <summary>Tests whether the Clearing event is fired</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestClearingEvent() {
|
public void TestClearingEvent() {
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
||||||
Method("Clearing");
|
Expect.Once.On(this.mockedSubscriber).Method("Cleared").WithAnyArguments();
|
||||||
|
|
||||||
this.observedCollection.Clear();
|
this.observedCollection.Clear();
|
||||||
|
|
||||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||||
|
@ -89,9 +96,7 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <summary>Tests whether the ItemAdded event is fired</summary>
|
/// <summary>Tests whether the ItemAdded event is fired</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestItemAddedEvent() {
|
public void TestItemAddedEvent() {
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||||
Method("ItemAdded").
|
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
this.observedCollection.Add(123);
|
this.observedCollection.Add(123);
|
||||||
|
|
||||||
|
@ -101,15 +106,11 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <summary>Tests whether the ItemRemoved event is fired</summary>
|
/// <summary>Tests whether the ItemRemoved event is fired</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestItemRemovedEvent() {
|
public void TestItemRemovedEvent() {
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||||
Method("ItemAdded").
|
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
this.observedCollection.Add(123);
|
this.observedCollection.Add(123);
|
||||||
|
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
Expect.Once.On(this.mockedSubscriber).Method("ItemRemoved").WithAnyArguments();
|
||||||
Method("ItemRemoved").
|
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
this.observedCollection.Remove(123);
|
this.observedCollection.Remove(123);
|
||||||
|
|
||||||
|
@ -119,28 +120,20 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <summary>Tests whether items in the collection can be replaced</summary>
|
/// <summary>Tests whether items in the collection can be replaced</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestItemReplacement() {
|
public void TestItemReplacement() {
|
||||||
Expect.Exactly(3).On(this.mockedSubscriber).
|
Expect.Exactly(3).On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||||
Method("ItemAdded").
|
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
this.observedCollection.Add(1);
|
this.observedCollection.Add(1);
|
||||||
this.observedCollection.Add(2);
|
this.observedCollection.Add(2);
|
||||||
this.observedCollection.Add(3);
|
this.observedCollection.Add(3);
|
||||||
|
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
Expect.Once.On(this.mockedSubscriber).Method("ItemRemoved").WithAnyArguments();
|
||||||
Method("ItemRemoved").
|
Expect.Once.On(this.mockedSubscriber).Method("ItemAdded").WithAnyArguments();
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
Expect.Once.On(this.mockedSubscriber).
|
|
||||||
Method("ItemAdded").
|
|
||||||
WithAnyArguments();
|
|
||||||
|
|
||||||
// Replace the middle item with something else
|
// Replace the middle item with something else
|
||||||
this.observedCollection[1] = 4;
|
this.observedCollection[1] = 4;
|
||||||
|
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
1,
|
1, this.observedCollection.IndexOf(4)
|
||||||
this.observedCollection.IndexOf(4)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||||
|
@ -153,10 +146,7 @@ namespace Nuclex.Support.Collections {
|
||||||
|
|
||||||
ObservableCollection<int> testCollection = new ObservableCollection<int>(integers);
|
ObservableCollection<int> testCollection = new ObservableCollection<int>(integers);
|
||||||
|
|
||||||
CollectionAssert.AreEqual(
|
CollectionAssert.AreEqual(integers, testCollection);
|
||||||
integers,
|
|
||||||
testCollection
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Mock object factory</summary>
|
/// <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.
|
/// to process the clearing of the entire collection as a special operation.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public event EventHandler Clearing;
|
public event EventHandler Clearing;
|
||||||
|
/// <summary>Raised when the collection has been cleared</summary>
|
||||||
|
public event EventHandler Cleared;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the ObservableCollection class that is empty.
|
/// 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>
|
/// <summary>Removes all elements from the Collection</summary>
|
||||||
protected override void ClearItems() {
|
protected override void ClearItems() {
|
||||||
OnClearing();
|
OnClearing();
|
||||||
|
|
||||||
base.ClearItems();
|
base.ClearItems();
|
||||||
|
OnCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -71,7 +73,6 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <param name="item">The zero-based index at which item should be inserted</param>
|
/// <param name="item">The zero-based index at which item should be inserted</param>
|
||||||
protected override void InsertItem(int index, ItemType item) {
|
protected override void InsertItem(int index, ItemType item) {
|
||||||
base.InsertItem(index, item);
|
base.InsertItem(index, item);
|
||||||
|
|
||||||
OnAdded(item);
|
OnAdded(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +82,7 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <param name="index">The zero-based index of the element to remove</param>
|
/// <param name="index">The zero-based index of the element to remove</param>
|
||||||
protected override void RemoveItem(int index) {
|
protected override void RemoveItem(int index) {
|
||||||
ItemType item = base[index];
|
ItemType item = base[index];
|
||||||
|
|
||||||
base.RemoveItem(index);
|
base.RemoveItem(index);
|
||||||
|
|
||||||
OnRemoved(item);
|
OnRemoved(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +94,7 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <param name="item">The zero-based index of the element to replace</param>
|
/// <param name="item">The zero-based index of the element to replace</param>
|
||||||
protected override void SetItem(int index, ItemType item) {
|
protected override void SetItem(int index, ItemType item) {
|
||||||
ItemType oldItem = base[index];
|
ItemType oldItem = base[index];
|
||||||
|
|
||||||
base.SetItem(index, item);
|
base.SetItem(index, item);
|
||||||
|
|
||||||
OnRemoved(oldItem);
|
OnRemoved(oldItem);
|
||||||
OnAdded(item);
|
OnAdded(item);
|
||||||
}
|
}
|
||||||
|
@ -122,6 +119,12 @@ namespace Nuclex.Support.Collections {
|
||||||
Clearing(this, EventArgs.Empty);
|
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
|
} // namespace Nuclex.Support.Collections
|
||||||
|
|
|
@ -45,6 +45,11 @@ namespace Nuclex.Support.Collections {
|
||||||
/// <param name="arguments">Not used</param>
|
/// <param name="arguments">Not used</param>
|
||||||
void Clearing(object sender, EventArgs arguments);
|
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>
|
/// <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="sender">Dictionary to which an item is being added</param>
|
||||||
/// <param name="arguments">Contains the item that 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(3, "three");
|
||||||
this.observedDictionary.Add(42, "forty-two");
|
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 +=
|
this.observedDictionary.ItemAdded +=
|
||||||
new EventHandler<ItemEventArgs<KeyValuePair<int, string>>>(
|
new EventHandler<ItemEventArgs<KeyValuePair<int, string>>>(
|
||||||
this.mockedSubscriber.ItemAdded
|
this.mockedSubscriber.ItemAdded
|
||||||
|
@ -293,6 +301,7 @@ namespace Nuclex.Support.Collections {
|
||||||
[Test]
|
[Test]
|
||||||
public void TestClearViaIDictionary() {
|
public void TestClearViaIDictionary() {
|
||||||
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
||||||
|
Expect.Once.On(this.mockedSubscriber).Method("Cleared").WithAnyArguments();
|
||||||
(this.observedDictionary as IDictionary).Clear();
|
(this.observedDictionary as IDictionary).Clear();
|
||||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||||
|
|
||||||
|
@ -424,6 +433,7 @@ namespace Nuclex.Support.Collections {
|
||||||
[Test]
|
[Test]
|
||||||
public void TestClearViaGenericICollection() {
|
public void TestClearViaGenericICollection() {
|
||||||
Expect.Once.On(this.mockedSubscriber).Method("Clearing").WithAnyArguments();
|
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.observedDictionary as ICollection<KeyValuePair<int, string>>).Clear();
|
||||||
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
this.mockery.VerifyAllExpectationsHaveBeenMet();
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace Nuclex.Support.Collections {
|
||||||
public event EventHandler<ItemEventArgs<KeyValuePair<KeyType, ValueType>>> ItemRemoved;
|
public event EventHandler<ItemEventArgs<KeyValuePair<KeyType, ValueType>>> ItemRemoved;
|
||||||
/// <summary>Raised when the dictionary is about to be cleared</summary>
|
/// <summary>Raised when the dictionary is about to be cleared</summary>
|
||||||
public event EventHandler Clearing;
|
public event EventHandler Clearing;
|
||||||
|
/// <summary>Raised when the dictionary has been cleared</summary>
|
||||||
|
public event EventHandler Cleared;
|
||||||
|
|
||||||
/// <summary>Initializes a new observable dictionary</summary>
|
/// <summary>Initializes a new observable dictionary</summary>
|
||||||
public ObservableDictionary() : this(new Dictionary<KeyType, ValueType>()) { }
|
public ObservableDictionary() : this(new Dictionary<KeyType, ValueType>()) { }
|
||||||
|
@ -220,6 +222,7 @@ namespace Nuclex.Support.Collections {
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
OnClearing();
|
OnClearing();
|
||||||
this.typedDictionary.Clear();
|
this.typedDictionary.Clear();
|
||||||
|
OnCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Fires the 'ItemAdded' event</summary>
|
/// <summary>Fires the 'ItemAdded' event</summary>
|
||||||
|
@ -242,6 +245,12 @@ namespace Nuclex.Support.Collections {
|
||||||
Clearing(this, EventArgs.Empty);
|
Clearing(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Fires the 'Cleared' event</summary>
|
||||||
|
protected virtual void OnCleared() {
|
||||||
|
if(Cleared != null)
|
||||||
|
Cleared(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
#region IEnumerable implementation
|
#region IEnumerable implementation
|
||||||
|
|
||||||
/// <summary>Returns a new object enumerator for the Dictionary</summary>
|
/// <summary>Returns a new object enumerator for the Dictionary</summary>
|
||||||
|
@ -337,6 +346,7 @@ namespace Nuclex.Support.Collections {
|
||||||
void ICollection<KeyValuePair<KeyType, ValueType>>.Clear() {
|
void ICollection<KeyValuePair<KeyType, ValueType>>.Clear() {
|
||||||
OnClearing();
|
OnClearing();
|
||||||
this.typedDictionary.Clear();
|
this.typedDictionary.Clear();
|
||||||
|
OnCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes all items from the Dictionary</summary>
|
/// <summary>Removes all items from the Dictionary</summary>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user