Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableCollection.cs @ 3013

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