diff --git a/Source/Collections/MultiDictionary.Test.cs b/Source/Collections/MultiDictionary.Test.cs
index 19310bc..f950252 100644
--- a/Source/Collections/MultiDictionary.Test.cs
+++ b/Source/Collections/MultiDictionary.Test.cs
@@ -41,6 +41,20 @@ namespace Nuclex.Support.Collections {
Assert.IsNotNull(dictionary); // nonsense, prevents compiler warning
}
+ ///
+ /// Verifies that the count is initialized correctly when building
+ /// a multi dictionary from a dictionary of value collections.
+ ///
+ [Test]
+ public void CountIsCalculatedIfInitializedFromDictionary() {
+ var contents = new Dictionary>();
+ contents.Add(1, new List(new string[] { "one", "eins" }));
+ contents.Add(2, new List(new string[] { "two", "zwei" }));
+
+ var multiDictionary = new MultiDictionary(contents);
+ Assert.AreEqual(4, multiDictionary.Count);
+ }
+
///
/// Verifies that a new multi dictionary based on a read-only dictionary is
/// also read-only
@@ -116,6 +130,15 @@ namespace Nuclex.Support.Collections {
Assert.AreEqual(1, dictionary.CountValues(30));
}
+ ///
+ /// Verifies that counting the values of a non-existing key returns 0
+ ///
+ [Test]
+ public void CountingValuesOfNonExistentKeyReturnsNull() {
+ var dictionary = new MultiDictionary();
+ Assert.AreEqual(0, dictionary.CountValues(1));
+ }
+
///
/// Ensures that its possible to remove values individually without affecting
/// other values stored under the same key
@@ -150,10 +173,39 @@ namespace Nuclex.Support.Collections {
dictionary.Add(10, "zehn");
Assert.AreEqual(2, dictionary.Count);
- var collectionOfCollections = (ICollection>>)dictionary;
+ var collectionOfCollections =
+ (ICollection>>)dictionary;
Assert.AreEqual(1, collectionOfCollections.Count);
}
+ ///
+ /// Verifies that the multi dictionary can be tested for containment of a specific value
+ ///
+ [Test]
+ public void ContainmentCanBeTested() {
+ var dictionary = new MultiDictionary();
+ dictionary.Add(10, "ten");
+ dictionary.Add(10, "zehn");
+
+ Assert.IsTrue(dictionary.Contains(new KeyValuePair(10, "ten")));
+ Assert.IsTrue(dictionary.Contains(new KeyValuePair(10, "zehn")));
+ Assert.IsFalse(dictionary.Contains(new KeyValuePair(10, "dix")));
+ Assert.IsFalse(dictionary.Contains(new KeyValuePair(20, "ten")));
+ }
+
+ ///
+ /// Verifies that the multi dictionary can be tested for containment of a specific key
+ ///
+ [Test]
+ public void KeyContainmentCanBeTested() {
+ var dictionary = new MultiDictionary();
+ dictionary.Add(10, "ten");
+ dictionary.Add(10, "zehn");
+
+ Assert.IsTrue(dictionary.ContainsKey(10));
+ Assert.IsFalse(dictionary.ContainsKey(20));
+ }
+
}
} // namespace Nuclex.Support.Collections
diff --git a/Source/Collections/MultiDictionary.cs b/Source/Collections/MultiDictionary.cs
index 5d335b3..9674990 100644
--- a/Source/Collections/MultiDictionary.cs
+++ b/Source/Collections/MultiDictionary.cs
@@ -333,15 +333,39 @@ namespace Nuclex.Support.Collections {
ICollection currentValues;
if(this.typedDictionary.TryGetValue(key, out currentValues)) {
- currentValues.Clear();
+ ValueList currentValueList = (ValueList)currentValues;
+
+ int index = 0;
+ foreach(TValue addedValue in value) {
+ if(index < currentValueList.Count) {
+ TValue original = currentValueList[index];
+ currentValueList[index] = addedValue;
+ OnReplaced(
+ new KeyValuePair(key, original),
+ new KeyValuePair(key, addedValue)
+ );
+ } else {
+ currentValueList.Add(addedValue);
+ OnAdded(new KeyValuePair(key, addedValue));
+ }
+ ++index;
+ }
+
+ int count = currentValueList.Count;
+ while(count > index) {
+ --count;
+ TValue removedValue = currentValueList[count];
+ currentValueList.RemoveAt(count);
+ OnRemoved(new KeyValuePair(key, removedValue));
+ }
} else {
currentValues = new ValueList(this);
this.typedDictionary.Add(key, currentValues);
- }
- foreach(TValue addedValue in value) {
- currentValues.Add(addedValue);
- OnAdded(new KeyValuePair(key, addedValue));
+ foreach(TValue addedValue in value) {
+ currentValues.Add(addedValue);
+ OnAdded(new KeyValuePair(key, addedValue));
+ }
}
}
}
@@ -420,6 +444,13 @@ namespace Nuclex.Support.Collections {
/// Item that has been removed from the collection
protected virtual void OnRemoved(KeyValuePair item) { }
+ /// Fires the 'ItemReplaced' event
+ /// Item that was replaced in the collection
+ /// Item that the original was replaced by
+ protected virtual void OnReplaced(
+ KeyValuePair oldItem, KeyValuePair newItem
+ ) { }
+
/// Fires the 'Clearing' event
protected virtual void OnClearing() { }
diff --git a/Source/Collections/ObservableSet.Test.cs b/Source/Collections/ObservableSet.Test.cs
index ddcaf36..a2954d1 100644
--- a/Source/Collections/ObservableSet.Test.cs
+++ b/Source/Collections/ObservableSet.Test.cs
@@ -31,12 +31,40 @@ using NMock;
namespace Nuclex.Support.Collections {
-#if false
/// Unit Test for the observable set wrapper
[TestFixture]
internal class ObservableSetTest {
+
+ #region interface IObservableCollectionSubscriber
+
+ public interface IObservableCollectionSubscriber {
+
+ /// Raised when an item has been added to the collection
+ event EventHandler> ItemAdded;
+ /// Raised when an item is removed from the collection
+ event EventHandler> ItemRemoved;
+ /// Raised when an item is replaced in the collection
+ event EventHandler> ItemReplaced;
+ /// Raised when the collection is about to be cleared
+ event EventHandler Clearing;
+ /// Raised when the collection has been cleared
+ event EventHandler Cleared;
+
+ }
+
+ #endregion // interface IObservableCollectionSubscriber
+
+
+
+ ///
+ /// Verifies that the observable set has a default constructor
+ ///
+ [Test]
+ public void HasDefaultConstructor() {
+ Assert.IsNotNull(new ObservableSet());
+ }
+
}
-#endif
} // namespace Nuclex.Support.Collections
diff --git a/Source/Collections/ObservableSet.cs b/Source/Collections/ObservableSet.cs
index f142888..76ad175 100644
--- a/Source/Collections/ObservableSet.cs
+++ b/Source/Collections/ObservableSet.cs
@@ -82,7 +82,11 @@ namespace Nuclex.Support.Collections {
/// True if the element was added, false if it was already contained in the set
///
public bool Add(TItem item) {
- return this.set.Add(item);
+ bool wasAdded = this.set.Add(item);
+ if(wasAdded) {
+ OnAdded(item);
+ }
+ return wasAdded;
}
/// Removes all elements that are contained in the collection