#region License Information
/* HeuristicLab
* Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using HEAL.Attic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace HeuristicLab.Collections {
[StorableType("98A1FFF8-88D8-4A1A-BDAA-BDC3F4663C1F")]
[Serializable]
public class ObservableCollection : IObservableCollection {
[Storable]
protected List list;
#region Properties
public int Capacity {
get { return list.Capacity; }
set {
if (list.Capacity != value) {
list.Capacity = value;
OnPropertyChanged("Capacity");
}
}
}
public int Count {
get { return list.Count; }
}
bool ICollection.IsReadOnly {
get { return ((ICollection)list).IsReadOnly; }
}
#endregion
#region Constructors
public ObservableCollection() {
list = new List();
}
public ObservableCollection(int capacity) {
list = new List(capacity);
}
public ObservableCollection(IEnumerable collection) {
list = new List(collection);
}
[StorableConstructor]
protected ObservableCollection(StorableConstructorFlag _) { }
#endregion
#region Access
public bool Contains(T item) {
return list.Contains(item);
}
public bool Exists(Predicate match) {
return list.Exists(match);
}
public T Find(Predicate match) {
return list.Find(match);
}
public ICollection FindAll(Predicate match) {
return list.FindAll(match);
}
public T FindLast(Predicate match) {
return list.FindLast(match);
}
#endregion
#region Manipulation
public void Add(T item) {
int capacity = list.Capacity;
list.Add(item);
if (list.Capacity != capacity)
OnPropertyChanged("Capacity");
OnPropertyChanged("Count");
OnItemsAdded(new T[] { item });
}
public void AddRange(IEnumerable collection) {
int capacity = list.Capacity;
ICollection items = collection as ICollection ?? collection.ToList();
list.AddRange(items);
if (items.Count > 0) {
if (list.Capacity != capacity)
OnPropertyChanged("Capacity");
OnPropertyChanged("Count");
OnItemsAdded(items);
}
}
public bool Remove(T item) {
if (list.Remove(item)) {
OnPropertyChanged("Count");
OnItemsRemoved(new T[] { item });
return true;
}
return false;
}
public void RemoveRange(IEnumerable collection) {
if (collection == null) throw new ArgumentNullException();
List items = new List();
foreach (T item in collection) {
if (list.Remove(item))
items.Add(item);
}
if (items.Count > 0) {
OnPropertyChanged("Count");
OnItemsRemoved(items);
}
}
public int RemoveAll(Predicate match) {
List items = list.FindAll(match);
int result = 0;
if (items.Count > 0) {
result = list.RemoveAll(match);
OnPropertyChanged("Count");
OnItemsRemoved(items);
}
return result;
}
public void Clear() {
if (list.Count > 0) {
T[] items = list.ToArray();
list.Clear();
OnPropertyChanged("Count");
OnCollectionReset(new T[0], items);
}
}
#endregion
#region Conversion
public ReadOnlyObservableCollection AsReadOnly() {
return new ReadOnlyObservableCollection(this);
}
public T[] ToArray() {
return list.ToArray();
}
public void CopyTo(T[] array, int arrayIndex) {
list.CopyTo(array, arrayIndex);
}
public ICollection ConvertAll(Converter converter) {
return list.ConvertAll(converter);
}
#endregion
#region Processing
public void ForEach(Action action) {
list.ForEach(action);
}
public bool TrueForAll(Predicate match) {
return list.TrueForAll(match);
}
#endregion
#region Enumeration
public IEnumerator GetEnumerator() {
return ((IEnumerable)list).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return ((IEnumerable)list).GetEnumerator();
}
#endregion
#region Helpers
public void TrimExcess() {
int capacity = list.Capacity;
list.TrimExcess();
if (list.Capacity != capacity)
OnPropertyChanged("Capacity");
}
#endregion
#region Events
[field: NonSerialized]
public event CollectionItemsChangedEventHandler ItemsAdded;
protected virtual void OnItemsAdded(IEnumerable items) {
CollectionItemsChangedEventHandler handler = ItemsAdded;
if (handler != null) handler(this, new CollectionItemsChangedEventArgs(items));
}
[field: NonSerialized]
public event CollectionItemsChangedEventHandler ItemsRemoved;
protected virtual void OnItemsRemoved(IEnumerable items) {
CollectionItemsChangedEventHandler handler = ItemsRemoved;
if (handler != null) handler(this, new CollectionItemsChangedEventArgs(items));
}
[field: NonSerialized]
public event CollectionItemsChangedEventHandler CollectionReset;
protected virtual void OnCollectionReset(IEnumerable items, IEnumerable oldItems) {
CollectionItemsChangedEventHandler handler = CollectionReset;
if (handler != null) handler(this, new CollectionItemsChangedEventArgs(items, oldItems));
}
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}