123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- using System;
- using System.Linq;
- using System.ComponentModel;
- using System.Collections.Generic;
- using System.Collections;
- #if NETFX_CORE
- using specialized = System.Collections.Specialized;
- #else
- using specialized = PlatformSupport.Collections.Specialized;
- #endif
- namespace PlatformSupport.Collections.ObjectModel
- {
- public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, specialized.INotifyCollectionChanged, INotifyPropertyChanged
- {
- private const string CountString = "Count";
- private const string IndexerName = "Item[]";
- private const string KeysName = "Keys";
- private const string ValuesName = "Values";
- private IDictionary<TKey, TValue> _Dictionary;
- protected IDictionary<TKey, TValue> Dictionary
- {
- get { return _Dictionary; }
- }
- #region Constructors
- public ObservableDictionary()
- {
- _Dictionary = new Dictionary<TKey, TValue>();
- }
- public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
- {
- _Dictionary = new Dictionary<TKey, TValue>(dictionary);
- }
- public ObservableDictionary(IEqualityComparer<TKey> comparer)
- {
- _Dictionary = new Dictionary<TKey, TValue>(comparer);
- }
- public ObservableDictionary(int capacity)
- {
- _Dictionary = new Dictionary<TKey, TValue>(capacity);
- }
- public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
- {
- _Dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
- }
- public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
- {
- _Dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
- }
- #endregion
- #region IDictionary<TKey,TValue> Members
- public void Add(TKey key, TValue value)
- {
- Insert(key, value, true);
- }
- public bool ContainsKey(TKey key)
- {
- return Dictionary.ContainsKey(key);
- }
- public ICollection<TKey> Keys
- {
- get { return Dictionary.Keys; }
- }
- public bool Remove(TKey key)
- {
- if (key == null) throw new ArgumentNullException("key");
- TValue value;
- Dictionary.TryGetValue(key, out value);
- var removed = Dictionary.Remove(key);
- if (removed)
- //OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value));
- OnCollectionChanged();
- return removed;
- }
- public bool TryGetValue(TKey key, out TValue value)
- {
- return Dictionary.TryGetValue(key, out value);
- }
- public ICollection<TValue> Values
- {
- get { return Dictionary.Values; }
- }
- public TValue this[TKey key]
- {
- get
- {
- return Dictionary[key];
- }
- set
- {
- Insert(key, value, false);
- }
- }
- #endregion
- #region ICollection<KeyValuePair<TKey,TValue>> Members
- public void Add(KeyValuePair<TKey, TValue> item)
- {
- Insert(item.Key, item.Value, true);
- }
- public void Clear()
- {
- if (Dictionary.Count > 0)
- {
- Dictionary.Clear();
- OnCollectionChanged();
- }
- }
- public bool Contains(KeyValuePair<TKey, TValue> item)
- {
- return Dictionary.Contains(item);
- }
- public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
- {
- Dictionary.CopyTo(array, arrayIndex);
- }
- public int Count
- {
- get { return Dictionary.Count; }
- }
- public bool IsReadOnly
- {
- get { return Dictionary.IsReadOnly; }
- }
- public bool Remove(KeyValuePair<TKey, TValue> item)
- {
- return Remove(item.Key);
- }
- #endregion
- #region IEnumerable<KeyValuePair<TKey,TValue>> Members
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
- {
- return Dictionary.GetEnumerator();
- }
- #endregion
- #region IEnumerable Members
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)Dictionary).GetEnumerator();
- }
- #endregion
- #region INotifyCollectionChanged Members
- public event specialized.NotifyCollectionChangedEventHandler CollectionChanged;
- #endregion
- #region INotifyPropertyChanged Members
- public event PropertyChangedEventHandler PropertyChanged;
- #endregion
- public void AddRange(IDictionary<TKey, TValue> items)
- {
- if (items == null) throw new ArgumentNullException("items");
- if (items.Count > 0)
- {
- if (Dictionary.Count > 0)
- {
- if (items.Keys.Any((k) => Dictionary.ContainsKey(k)))
- throw new ArgumentException("An item with the same key has already been added.");
- else
- foreach (var item in items) Dictionary.Add(item);
- }
- else
- _Dictionary = new Dictionary<TKey, TValue>(items);
- OnCollectionChanged(specialized.NotifyCollectionChangedAction.Add, items.ToArray());
- }
- }
- private void Insert(TKey key, TValue value, bool add)
- {
- if (key == null) throw new ArgumentNullException("key");
- TValue item;
- if (Dictionary.TryGetValue(key, out item))
- {
- if (add) throw new ArgumentException("An item with the same key has already been added.");
- if (Equals(item, value)) return;
- Dictionary[key] = value;
- OnCollectionChanged(specialized.NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item));
- }
- else
- {
- Dictionary[key] = value;
- OnCollectionChanged(specialized.NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value));
- }
- }
- private void OnPropertyChanged()
- {
- OnPropertyChanged(CountString);
- OnPropertyChanged(IndexerName);
- OnPropertyChanged(KeysName);
- OnPropertyChanged(ValuesName);
- }
- protected virtual void OnPropertyChanged(string propertyName)
- {
- if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- private void OnCollectionChanged()
- {
- OnPropertyChanged();
- if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(specialized.NotifyCollectionChangedAction.Reset));
- }
- private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem)
- {
- OnPropertyChanged();
- if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, changedItem));
- }
- private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
- {
- OnPropertyChanged();
- if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, newItem, oldItem));
- }
- private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, IList newItems)
- {
- OnPropertyChanged();
- if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, newItems));
- }
- }
- }
|