Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableCollection.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: 7.3 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 HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27
28namespace HeuristicLab.Collections {
29  [Serializable]
30  [StorableClass]
31  public class ObservableCollection<T> : IObservableCollection<T> {
32    [Storable]
33    protected List<T> list;
34
35    #region Properties
36    [Storable]
37    private bool readOnlyView;
38    public bool ReadOnlyView {
39      get { return readOnlyView; }
40      set {
41        if (readOnlyView != value) {
42          readOnlyView = value;
43          OnReadOnlyViewChanged();
44          OnPropertyChanged("ReadOnlyView");
45        }
46      }
47    }
48
49    public int Capacity {
50      get { return list.Capacity; }
51      set {
52        if (list.Capacity != value) {
53          list.Capacity = value;
54          OnPropertyChanged("Capacity");
55        }
56      }
57    }
58    public int Count {
59      get { return list.Count; }
60    }
61    bool ICollection<T>.IsReadOnly {
62      get { return ((ICollection<T>)list).IsReadOnly; }
63    }
64    #endregion
65
66    #region Constructors
67    public ObservableCollection() {
68      list = new List<T>();
69      readOnlyView = ((ICollection<T>)list).IsReadOnly;
70    }
71    public ObservableCollection(int capacity) {
72      list = new List<T>(capacity);
73      readOnlyView = ((ICollection<T>)list).IsReadOnly;
74    }
75    public ObservableCollection(IEnumerable<T> collection) {
76      list = new List<T>(collection);
77      readOnlyView = ((ICollection<T>)list).IsReadOnly;
78    }
79    #endregion
80
81    #region Access
82    public bool Contains(T item) {
83      return list.Contains(item);
84    }
85
86    public bool Exists(Predicate<T> match) {
87      return list.Exists(match);
88    }
89
90    public T Find(Predicate<T> match) {
91      return list.Find(match);
92    }
93    public ICollection<T> FindAll(Predicate<T> match) {
94      return list.FindAll(match);
95    }
96    public T FindLast(Predicate<T> match) {
97      return list.FindLast(match);
98    }
99    #endregion
100
101    #region Manipulation
102    public void Add(T item) {
103      int capacity = list.Capacity;
104      list.Add(item);
105      if (list.Capacity != capacity)
106        OnPropertyChanged("Capacity");
107      OnPropertyChanged("Count");
108      OnItemsAdded(new T[] { item });
109    }
110    public void AddRange(IEnumerable<T> collection) {
111      int capacity = list.Capacity;
112      int count = list.Count;
113      list.AddRange(collection);
114      if (list.Count != count) {
115        if (list.Capacity != capacity)
116          OnPropertyChanged("Capacity");
117        OnPropertyChanged("Count");
118        OnItemsAdded(collection);
119      }
120    }
121
122    public bool Remove(T item) {
123      if (list.Remove(item)) {
124        OnPropertyChanged("Count");
125        OnItemsRemoved(new T[] { item });
126        return true;
127      }
128      return false;
129    }
130    public void RemoveRange(IEnumerable<T> collection) {
131      if (collection == null) throw new ArgumentNullException();
132      List<T> items = new List<T>();
133      foreach (T item in collection) {
134        if (list.Remove(item))
135          items.Add(item);
136      }
137      if (items.Count > 0) {
138        OnPropertyChanged("Count");
139        OnItemsRemoved(items);
140      }
141    }
142    public int RemoveAll(Predicate<T> match) {
143      List<T> items = list.FindAll(match);
144      int result = 0;
145      if (items.Count > 0) {
146        result = list.RemoveAll(match);
147        OnPropertyChanged("Count");
148        OnItemsRemoved(items);
149      }
150      return result;
151    }
152
153    public void Clear() {
154      if (list.Count > 0) {
155        T[] items = list.ToArray();
156        list.Clear();
157        OnPropertyChanged("Count");
158        OnCollectionReset(new T[0], items);
159      }
160    }
161    #endregion
162
163    #region Conversion
164    public ReadOnlyObservableCollection<T> AsReadOnly() {
165      return new ReadOnlyObservableCollection<T>(this);
166    }
167    public T[] ToArray() {
168      return list.ToArray();
169    }
170    public void CopyTo(T[] array, int arrayIndex) {
171      list.CopyTo(array, arrayIndex);
172    }
173    public ICollection<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter) {
174      return list.ConvertAll<TOutput>(converter);
175    }
176    #endregion
177
178    #region Processing
179    public void ForEach(Action<T> action) {
180      list.ForEach(action);
181    }
182    public bool TrueForAll(Predicate<T> match) {
183      return list.TrueForAll(match);
184    }
185    #endregion
186
187    #region Enumeration
188    public IEnumerator<T> GetEnumerator() {
189      return ((IEnumerable<T>)list).GetEnumerator();
190    }
191    IEnumerator IEnumerable.GetEnumerator() {
192      return ((IEnumerable)list).GetEnumerator();
193    }
194    #endregion
195
196    #region Helpers
197    public void TrimExcess() {
198      int capacity = list.Capacity;
199      list.TrimExcess();
200      if (list.Capacity != capacity)
201        OnPropertyChanged("Capacity");
202    }
203    #endregion
204
205    #region Events
206    [field: NonSerialized]
207    public event EventHandler ReadOnlyViewChanged;
208    protected virtual void OnReadOnlyViewChanged() {
209      EventHandler handler = ReadOnlyViewChanged;
210      if (handler != null) handler(this, EventArgs.Empty);
211    }
212
213    [field: NonSerialized]
214    public event CollectionItemsChangedEventHandler<T> ItemsAdded;
215    protected virtual void OnItemsAdded(IEnumerable<T> items) {
216      CollectionItemsChangedEventHandler<T> handler = ItemsAdded;
217      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<T>(items));
218    }
219
220    [field: NonSerialized]
221    public event CollectionItemsChangedEventHandler<T> ItemsRemoved;
222    protected virtual void OnItemsRemoved(IEnumerable<T> items) {
223      CollectionItemsChangedEventHandler<T> handler = ItemsRemoved;
224      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<T>(items));
225    }
226
227    [field: NonSerialized]
228    public event CollectionItemsChangedEventHandler<T> CollectionReset;
229    protected virtual void OnCollectionReset(IEnumerable<T> items, IEnumerable<T> oldItems) {
230      CollectionItemsChangedEventHandler<T> handler = CollectionReset;
231      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<T>(items, oldItems));
232    }
233
234    [field: NonSerialized]
235    public event PropertyChangedEventHandler PropertyChanged;
236    protected virtual void OnPropertyChanged(string propertyName) {
237      PropertyChangedEventHandler handler = PropertyChanged;
238      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
239    }
240    #endregion
241  }
242}
Note: See TracBrowser for help on using the repository browser.