Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2995 was 2994, checked in by epitzer, 14 years ago

Make StorableClass attribute compulsory for StorableSerializer to work, add named property StorableClassType to choose between Empty and MarkedOnly, later other options will be added. (#548)

File size: 8.1 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(StorableClassType.MarkedOnly)]
32  public class ObservableDictionary<TKey, TValue> : IObservableDictionary<TKey, TValue> {
33    [Storable]
34    private Dictionary<TKey, TValue> dict;
35
36    #region Properties
37    public ICollection<TKey> Keys {
38      get { return dict.Keys; }
39    }
40    public ICollection<TValue> Values {
41      get { return dict.Values; }
42    }
43    public int Count {
44      get { return dict.Count; }
45    }
46    public IEqualityComparer<TKey> Comparer {
47      get { return dict.Comparer; }
48    }
49    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
50      get { return ((ICollection<KeyValuePair<TKey, TValue>>)dict).IsReadOnly; }
51    }
52
53    public TValue this[TKey key] {
54      get {
55        return dict[key];
56      }
57      set {
58        if (dict.ContainsKey(key)) {
59          KeyValuePair<TKey, TValue> item = new KeyValuePair<TKey, TValue>(key, dict[key]);
60          dict[key] = value;
61          OnItemsReplaced(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) }, new KeyValuePair<TKey, TValue>[] { item });
62        } else {
63          dict[key] = value;
64          OnItemsAdded(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
65        }
66      }
67    }
68    #endregion
69
70    #region Constructors
71    public ObservableDictionary() {
72      dict = new Dictionary<TKey, TValue>();
73    }
74    public ObservableDictionary(int capacity) {
75      dict = new Dictionary<TKey, TValue>(capacity);
76    }
77    public ObservableDictionary(IEqualityComparer<TKey> comparer) {
78      dict = new Dictionary<TKey, TValue>(comparer);
79    }
80    public ObservableDictionary(IDictionary<TKey, TValue> dictionary) {
81      dict = new Dictionary<TKey, TValue>(dictionary);
82    }
83    public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer) {
84      dict = new Dictionary<TKey, TValue>(capacity, comparer);
85    }
86    public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) {
87      dict = new Dictionary<TKey, TValue>(dictionary, comparer);
88    }
89    #endregion
90
91    #region Access
92    public bool ContainsKey(TKey key) {
93      return dict.ContainsKey(key);
94    }
95    public bool ContainsValue(TValue value) {
96      return dict.ContainsValue(value);
97    }
98    bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) {
99      return dict.Contains(item);
100    }
101
102    public bool TryGetValue(TKey key, out TValue value) {
103      return dict.TryGetValue(key, out value);
104    }
105    #endregion
106
107    #region Manipulation
108    public void Add(TKey key, TValue value) {
109      dict.Add(key, value);
110      OnPropertyChanged("Item[]");
111      OnPropertyChanged("Keys");
112      OnPropertyChanged("Values");
113      OnPropertyChanged("Count");
114      OnItemsAdded(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
115    }
116    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) {
117      ((ICollection<KeyValuePair<TKey, TValue>>)dict).Add(item);
118      OnPropertyChanged("Item[]");
119      OnPropertyChanged("Keys");
120      OnPropertyChanged("Values");
121      OnPropertyChanged("Count");
122      OnItemsAdded(new KeyValuePair<TKey, TValue>[] { item });
123    }
124
125    public bool Remove(TKey key) {
126      TValue value;
127      if (dict.TryGetValue(key, out value)) {
128        dict.Remove(key);
129        OnPropertyChanged("Item[]");
130        OnPropertyChanged("Keys");
131        OnPropertyChanged("Values");
132        OnPropertyChanged("Count");
133        OnItemsRemoved(new KeyValuePair<TKey, TValue>[] { new KeyValuePair<TKey, TValue>(key, value) });
134        return true;
135      }
136      return false;
137    }
138    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) {
139      if (((ICollection<KeyValuePair<TKey, TValue>>)dict).Remove(item)) {
140        OnPropertyChanged("Item[]");
141        OnPropertyChanged("Keys");
142        OnPropertyChanged("Values");
143        OnPropertyChanged("Count");
144        OnItemsRemoved(new KeyValuePair<TKey, TValue>[] { item });
145        return true;
146      }
147      return false;
148    }
149
150    public void Clear() {
151      if (dict.Count > 0) {
152        KeyValuePair<TKey, TValue>[] items = dict.ToArray();
153        dict.Clear();
154        OnPropertyChanged("Item[]");
155        OnPropertyChanged("Keys");
156        OnPropertyChanged("Values");
157        OnPropertyChanged("Count");
158        OnCollectionReset(new KeyValuePair<TKey, TValue>[0], items);
159      }
160    }
161    #endregion
162
163    #region Conversion
164    public ReadOnlyObservableDictionary<TKey, TValue> AsReadOnly() {
165      return new ReadOnlyObservableDictionary<TKey, TValue>(this);
166    }
167    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
168      ((ICollection<KeyValuePair<TKey, TValue>>)dict).CopyTo(array, arrayIndex);
169    }
170    #endregion
171
172    #region Enumeration
173    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
174      return dict.GetEnumerator();
175    }
176    IEnumerator IEnumerable.GetEnumerator() {
177      return dict.GetEnumerator();
178    }
179    #endregion
180
181    #region Events
182    [field: NonSerialized]
183    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsAdded;
184    protected virtual void OnItemsAdded(IEnumerable<KeyValuePair<TKey, TValue>> items) {
185      if (ItemsAdded != null)
186        ItemsAdded(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items));
187    }
188
189    [field: NonSerialized]
190    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsRemoved;
191    protected virtual void OnItemsRemoved(IEnumerable<KeyValuePair<TKey, TValue>> items) {
192      if (ItemsRemoved != null)
193        ItemsRemoved(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items));
194    }
195
196    [field: NonSerialized]
197    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> ItemsReplaced;
198    protected virtual void OnItemsReplaced(IEnumerable<KeyValuePair<TKey, TValue>> items, IEnumerable<KeyValuePair<TKey, TValue>> oldItems) {
199      if (ItemsReplaced != null)
200        ItemsReplaced(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items, oldItems));
201    }
202
203    [field: NonSerialized]
204    public event CollectionItemsChangedEventHandler<KeyValuePair<TKey, TValue>> CollectionReset;
205    protected virtual void OnCollectionReset(IEnumerable<KeyValuePair<TKey, TValue>> items, IEnumerable<KeyValuePair<TKey, TValue>> oldItems) {
206      if (CollectionReset != null)
207        CollectionReset(this, new CollectionItemsChangedEventArgs<KeyValuePair<TKey, TValue>>(items, oldItems));
208    }
209
210    [field: NonSerialized]
211    public event PropertyChangedEventHandler PropertyChanged;
212    protected virtual void OnPropertyChanged(string propertyName) {
213      if (PropertyChanged != null)
214        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
215    }
216    #endregion
217  }
218}
Note: See TracBrowser for help on using the repository browser.