Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2751 was 2620, checked in by swagner, 15 years ago

Implemented INotifyPropertyChanged in all observable collections (#819)

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