Merge pull request #2408 from tastywheattasteslikechicken/MoreInterfaceSupport
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / DictionaryItemsCollection.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Activities.Presentation
6 {
7     using System.Activities.Presentation.Model;
8     using System.Collections.Generic;
9     using System.Collections.ObjectModel;
10     using System.Runtime;
11
12     class DictionaryItemsCollection<TKey, TValue> : Collection<ModelItemKeyValuePair<TKey, TValue>>, IItemsCollection
13     {
14         IDictionary<TKey, TValue> dictionary;
15         public bool ShouldUpdateDictionary { get; set; }
16         public ModelItemDictionaryImpl ModelDictionary { get; set; }
17
18         public DictionaryItemsCollection(object dictionary)
19         {
20             this.ShouldUpdateDictionary = true;
21             this.dictionary = dictionary as IDictionary<TKey, TValue>;
22             Fx.Assert(this.dictionary != null, "dictionary should be instantiated");
23             foreach (KeyValuePair<TKey, TValue> kvpair in this.dictionary)
24             {
25                 ModelItemKeyValuePair<TKey, TValue> item = new ModelItemKeyValuePair<TKey, TValue>(kvpair.Key, kvpair.Value);
26                 item.collection = this;
27                 base.InsertItem(this.Count, item);
28             }
29         }
30
31         internal void PostUpdateKey()
32         {
33             this.UpdateDictionary();
34         }
35
36         internal void PreUpdateKey(TKey oldKey, TKey newKey)
37         {
38             this.dictionary.Remove(oldKey);
39             if (this.dictionary.ContainsKey(newKey))
40             {
41                 this.UpdateDictionary();
42                 throw FxTrace.Exception.AsError(new ArgumentException(SR.DuplicateKey));
43             }
44             if (this.ModelDictionary != null)
45             {
46                 this.ModelDictionary.UpdateKey(oldKey, newKey);
47             }
48         }
49
50         internal void UpdateValue(TKey key, TValue value)
51         {
52             if (ShouldUpdateDictionary)
53             {
54                 this.dictionary[key] = value;
55                 if (this.ModelDictionary != null)
56                 {
57                     this.ModelDictionary.UpdateValue(key, value);
58                 }
59             }
60         }
61
62         protected override void ClearItems()
63         {
64             if (ShouldUpdateDictionary)
65             {
66                 this.dictionary.Clear();
67             }
68             base.ClearItems();
69         }
70
71         protected override void InsertItem(int index, ModelItemKeyValuePair<TKey, TValue> item)
72         {
73             if (item == null)
74             {
75                 throw FxTrace.Exception.AsError(new ArgumentNullException("item"));
76             }
77
78             if (ShouldUpdateDictionary && this.dictionary.ContainsKey(item.Key))
79             {
80                 throw FxTrace.Exception.AsError(new ArgumentException(SR.DuplicateKey));
81             }
82
83             item.collection = this;
84             base.InsertItem(index, item);
85
86             this.UpdateDictionary();
87         }
88
89         protected override void RemoveItem(int index)
90         {
91             ModelItemKeyValuePair<TKey, TValue> item = this[index];
92             Fx.Assert(item != null, "Item should not be null.");
93             if (ShouldUpdateDictionary)
94             {
95                 this.dictionary.Remove(item.Key);
96             }
97
98             base.RemoveItem(index);
99         }
100
101         protected override void SetItem(int index, ModelItemKeyValuePair<TKey, TValue> item)
102         {
103             if (item == null)
104             {
105                 throw FxTrace.Exception.AsError(new ArgumentNullException("item"));
106             }
107             item.collection = this;
108             ModelItemKeyValuePair<TKey, TValue> oldItem = this[index];
109             Fx.Assert(oldItem != null, "Item should not be null.");
110             this.PreUpdateKey(oldItem.Key, item.Key);
111             base.SetItem(index, item);
112             this.PostUpdateKey();
113         }
114
115         void UpdateDictionary()
116         {
117             if (ShouldUpdateDictionary)
118             {
119                 // Make sure the order of KVPairs in the dictionary is the same as the order of items in the collection
120                 this.dictionary.Clear();
121                 foreach (ModelItemKeyValuePair<TKey, TValue> item in this)
122                 {
123                     this.dictionary.Add(new KeyValuePair<TKey, TValue>(item.Key, item.Value));
124                 }
125             }
126         }
127
128     }
129 }