Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableDictionary.cs @ 3317

Last change on this file since 3317 was 3317, checked in by swagner, 14 years ago

Implemented ReadOnlyView property for items (#969).

File size: 9.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.ComponentModel;
26using System.Linq;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Collections {
30  [Serializable]
31  [StorableClass]
32  public class ObservableDictionary<TKey, TValue> : IObservableDictionary<TKey, TValue> {
33    [Storable]
34    private Dictionary<TKey, TValue> dict;
35
36    #region Properties
37    [Storable]
38    private bool readOnlyView;
39    public bool ReadOnlyView {
40      get { return readOnlyView; }
41      set {
42        if (readOnlyView != value) {
43          readOnlyView = value;
44          OnReadOnlyViewChanged();
45          OnPropertyChanged("ReadOnlyView");
46        }
47      }
48    }
49
50    public ICollection<TKey> Keys {
51      get { return dict.Keys; }
52    }
53    public ICollection<TValue> Values {
54      get { return dict.Values; }
55    }
56    public int Count {
57      get { return dict.Count; }
58    }
59    public IEqualityComparer<TKey> Comparer {
60      get { return dict.Comparer; }
61    }
62    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
63      get { return ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly; }
64    }
65
66    public TValue this[TKey key] {
67      get {
68        return dict[key];
69      }
70      set {
71        if (dict.ContainsKey(key)) {
72          KeyValuePair<TKey, TValue> item = new KeyValuePair<TKey, TValue>(key, dict[key]);
73          dict[key] = value;
74          OnItemsReplaced(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) }, new KeyValuePair<TKey, TValue>[] { item });
75        } else {
76          dict[key] = value;
77          OnItemsAdded(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
78        }
79      }
80    }
81    #endregion
82
83    #region Constructors
84    public ObservableDictionary() {
85      dict = new Dictionary<TKey, TValue>();
86      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
87    }
88    public ObservableDictionary(int capacity) {
89      dict = new Dictionary<TKey, TValue>(capacity);
90      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
91    }
92    public ObservableDictionary(IEqualityComparer<TKey> comparer) {
93      dict = new Dictionary<TKey, TValue>(comparer);
94      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
95    }
96    public ObservableDictionary(IDictionary<TKey, TValue> dictionary) {
97      dict = new Dictionary<TKey, TValue>(dictionary);
98      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
99    }
100    public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer) {
101      dict = new Dictionary<TKey, TValue>(capacity, comparer);
102      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
103    }
104    public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) {
105      dict = new Dictionary<TKey, TValue>(dictionary, comparer);
106      readOnlyView = ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly;
107    }
108    #endregion
109
110    #region Access
111    public bool ContainsKey(TKey key) {
112      return dict.ContainsKey(key);
113    }
114    public bool ContainsValue(TValue value) {
115      return dict.ContainsValue(value);
116    }
117    bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) {
118      return dict.Contains(item);
119    }
120
121    public bool TryGetValue(TKey key, out TValue value) {
122      return dict.TryGetValue(key, out value);
123    }
124    #endregion
125
126    #region Manipulation
127    public void Add(TKey key, TValue value) {
128      dict.Add(key, value);
129      OnPropertyChanged("Item[]");
130      OnPropertyChanged("Keys");
131      OnPropertyChanged("Values");
132      OnPropertyChanged("Count");
133      OnItemsAdded(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
134    }
135    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) {
136      ((ICollection<KeyValuePair<TKey, TValue>>)dict).Add(item);
137      OnPropertyChanged("Item[]");
138      OnPropertyChanged("Keys");
139      OnPropertyChanged("Values");
140      OnPropertyChanged("Count");
141      OnItemsAdded(new KeyValuePair<TKey, TValue>[] { item });
142    }
143
144    public bool Remove(TKey key) {
145      TValue value;
146      if (dict.TryGetValue(key, out value)) {
147        dict.Remove(key);
148        OnPropertyChanged("Item[]");
149        OnPropertyChanged("Keys");
150        OnPropertyChanged("Values");
151        OnPropertyChanged("Count");
152        OnItemsRemoved(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
153        return true;
154      }
155      return false;
156    }
157    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) {
158      if (((ICollection<KeyValuePair<TKey, TValue>>)dict).Remove(item)) {
159        OnPropertyChanged("Item[]");
160        OnPropertyChanged("Keys");
161        OnPropertyChanged("Values");
162        OnPropertyChanged("Count");
163        OnItemsRemoved(new KeyValuePair<TKey, TValue>[] { item });
164        return true;
165      }
166      return false;
167    }
168
169    public void Clear() {
170      if (dict.Count > 0) {
171        KeyValuePair<TKey, TValue>[] items = dict.ToArray();
172        dict.Clear();
173        OnPropertyChanged("Item[]");
174        OnPropertyChanged("Keys");
175        OnPropertyChanged("Values");
176        OnPropertyChanged("Count");
177        OnCollectionReset(new KeyValuePair<TKey, TValue>[0], items);
178      }
179    }
180    #endregion
181
182    #region Conversion
183    public ReadOnlyObservableDictionary<TKey, TValue> AsReadOnly() {
184      return new ReadOnlyObservableDictionary<TKey, TValue>(this);
185    }
186    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
187      ((ICollection<KeyValuePair<TKey, TValue>>)dict).CopyTo(array, arrayIndex);
188    }
189    #endregion
190
191    #region Enumeration
192    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
193      return dict.GetEnumerator();
194    }
195    IEnumerator IEnumerable.GetEnumerator() {
196      return dict.GetEnumerator();
197    }
198    #endregion
199
200    #region Events
201    [field: NonSerialized]
202    public event EventHandler ReadOnlyViewChanged;
203    protected virtual void OnReadOnlyViewChanged() {
204      EventHandler handler = ReadOnlyViewChanged;
205      if (handler != null) handler(this, EventArgs.Empty);
206    }
207
208    [field: NonSerialized]
209    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsAdded;
210    protected virtual void OnItemsAdded(IEnumerable<KeyValuePair<TKey, TValue>> items) {
211      CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> handler = ItemsAdded;
212      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items));
213    }
214
215    [field: NonSerialized]
216    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsRemoved;
217    protected virtual void OnItemsRemoved(IEnumerable<KeyValuePair<TKey, TValue>> items) {
218      CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> handler = ItemsRemoved;
219      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items));
220    }
221
222    [field: NonSerialized]
223    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsReplaced;
224    protected virtual void OnItemsReplaced(IEnumerable<KeyValuePair<TKey, TValue>> items, IEnumerable<KeyValuePair<TKey, TValue>> oldItems) {
225      CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> handler = ItemsReplaced;
226      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items, oldItems));
227    }
228
229    [field: NonSerialized]
230    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> CollectionReset;
231    protected virtual void OnCollectionReset(IEnumerable<KeyValuePair<TKey, TValue>> items, IEnumerable<KeyValuePair<TKey, TValue>> oldItems) {
232      CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> handler = CollectionReset;
233      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items, oldItems));
234    }
235
236    [field: NonSerialized]
237    public event PropertyChangedEventHandler PropertyChanged;
238    protected virtual void OnPropertyChanged(string propertyName) {
239      PropertyChangedEventHandler handler = PropertyChanged;
240      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
241    }
242    #endregion
243  }
244}
Note: See TracBrowser for help on using the repository browser.