123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- /* Turn off documentation warnings in this file. Generally they are
- * relevant in this library, but not for this file since it is mostly
- * methods found in normal List<> class, and thus it is no need to write
- * that comments once again with the drawback of making it hard to read.
- */
- #pragma warning disable 1591
- namespace Wayne.Lib
- {
- /// <summary>
- /// Extends the IList interface with some more members found in List class.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public interface IAdvancedList<T> : IList<T>
- {
- void AddRange(IEnumerable<T> collection);
- ReadOnlyCollection<T> AsReadOnly();
- void CopyTo(T[] array);
- void CopyTo(int index, T[] array, int arrayIndex, int count);
- void BeginUpdate();
- void EndUpdate();
- }
- /// <summary>
- /// Extends IAdvanced List with an event handler that makes it possible to
- /// follow when the contents has benn changed.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public interface IObservableList<T> : IAdvancedList<T>
- {
- event EventHandler Changed;
- }
- /// <summary>
- /// Observable list is a list class similar to .Net's List but with an
- /// event that notifies when something has been changed in the list.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public class ObservableList<T> : IObservableList<T>, IList
- {
- private object syncRoot;
- private readonly List<T> internalList = new List<T>();
- private int updateCount;
- private bool updated;
- public IEnumerator<T> GetEnumerator()
- {
- return internalList.GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- public int Count
- {
- get { return internalList.Count; }
- }
- int ICollection.Count
- {
- get { return Count; }
- }
- public bool Contains(T item)
- {
- return internalList.Contains(item);
- }
- public bool Contains(object value)
- {
- return IsCompatibleObject(value) && Contains((T)value);
- }
- public void Clear()
- {
- if (internalList.Count > 0)
- {
- internalList.Clear();
- ListChanged();
- }
- }
- void IList.Clear()
- {
- Clear();
- }
- public int IndexOf(T item)
- {
- return internalList.IndexOf(item);
- }
- int IList.IndexOf(object value)
- {
- return IsCompatibleObject(value) ? IndexOf((T)value) : -1;
- }
- public T this[int index]
- {
- get { return internalList[index]; }
- set
- {
- internalList[index] = value;
- ListChanged();
- }
- }
- object IList.this[int index]
- {
- get { return internalList[index]; }
- set
- {
- VerifyValueType(value);
- this[index] = (T)value;
- }
- }
- public void Add(T item)
- {
- internalList.Add(item);
- ListChanged();
- }
- public int Add(object value)
- {
- VerifyValueType(value);
- Add((T)value);
- return Count - 1;
- }
- public void AddRange(IEnumerable<T> collection)
- {
- internalList.AddRange(collection);
- ListChanged();
- }
- public ReadOnlyCollection<T> AsReadOnly()
- {
- return new ReadOnlyCollection<T>(internalList);
- }
- public void Insert(int index, T item)
- {
- internalList.Insert(index, item);
- ListChanged();
- }
- public void Insert(int index, object value)
- {
- VerifyValueType(value);
- Insert(index, (T)value);
- }
- public bool Remove(T item)
- {
- if (internalList.Remove(item))
- {
- ListChanged();
- return true;
- }
- return false;
- }
- public void Remove(object value)
- {
- VerifyValueType(value);
- Remove((T)value);
- }
- public void RemoveAt(int index)
- {
- internalList.RemoveAt(index);
- ListChanged();
- }
- void IList.RemoveAt(int index)
- {
- RemoveAt(index);
- }
- bool IList.IsReadOnly
- {
- get { return false; }
- }
- public bool IsFixedSize
- {
- get { return false; }
- }
- public void CopyTo(T[] array)
- {
- internalList.CopyTo(array);
- }
- public void CopyTo(T[] array, int arrayIndex)
- {
- internalList.CopyTo(array, arrayIndex);
- }
- public void CopyTo(int index, T[] array, int arrayIndex, int count)
- {
- internalList.CopyTo(index, array, arrayIndex, count);
- }
- public void CopyTo(Array array, int index)
- {
- if ((array != null) && (array.Rank != 1))
- throw new ArgumentException("Only single dimensional arrays are supported for the requested action.");
- try
- {
- Array.Copy(internalList.ToArray(), 0, array, index, internalList.Count);
- }
- catch (ArrayTypeMismatchException)
- {
- throw new ArgumentException("Target array type is not compatible with the type of items in the collection.");
- }
- }
- public object SyncRoot
- {
- get
- {
- if (syncRoot == null)
- System.Threading.Interlocked.CompareExchange(ref syncRoot, new object(), null);
- return syncRoot;
- }
- }
- public bool IsSynchronized
- {
- get { return false; }
- }
- public bool IsReadOnly
- {
- get { return IsReadOnly; }
- }
- private static bool IsCompatibleObject(object value)
- {
- return (value is T) || (value == null && !typeof(T).IsValueType);
- }
- private static void VerifyValueType(object value)
- {
- if (!IsCompatibleObject(value))
- throw new ArgumentException(string.Concat("The value \"", value.GetType(), "\" is not of type \"", typeof(T), "\" and cannot be used in this generic collection."));
- }
- public event EventHandler Changed;
- public void BeginUpdate()
- {
- updateCount++;
- }
- public void EndUpdate()
- {
- updateCount--;
- if ((updateCount == 0) && updated)
- {
- updated = false;
- ListChanged();
- }
- }
- private void ListChanged()
- {
- if (updateCount > 0)
- {
- updated = true;
- return;
- }
- if (Changed != null)
- Changed(this, EventArgs.Empty);
- }
- }
- }
|