Website may be up and down over next few months. I'm currently doing a complete overhaul of everything. Going back to simple individual .htm pages, new overall site theme, sanitizing and cleaning up html of all pages and blog posts, attempting to implement a new tooling and publishing system etc etc.

ObservableDictionary

 public class ObservableDictionary : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
    {
        private const string CountString = "Count";
        private const string IndexerName = "Item[]";
        private const string KeysName = "Keys";
        private const string ValuesName = "Values";

        private IDictionary _Dictionary;
        private readonly IList> _BaseCollection;
        private readonly IDictionary _IndexDictionary;


        protected IDictionary Dictionary
        {
            get { return _Dictionary; }
        }

        #region Constructors
        public ObservableDictionary()
        {
            _Dictionary = new Dictionary();
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
        }
        public ObservableDictionary(IDictionary dictionary)
        {
            _Dictionary = new Dictionary(dictionary);
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
            if (dictionary != null)
                foreach (var pair in dictionary)
                    ((IDictionary)this).Add(pair);
        }
        public ObservableDictionary(IEqualityComparer comparer)
        {
            _Dictionary = new Dictionary(comparer);
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
        }
        public ObservableDictionary(int capacity)
        {
            _Dictionary = new Dictionary(capacity);
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
        }
        public ObservableDictionary(IDictionary dictionary, IEqualityComparer comparer)
        {
            _Dictionary = new Dictionary(dictionary, comparer);
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
            if (dictionary != null)
                foreach (var pair in dictionary)
                    ((IDictionary)this).Add(pair);
        }
        public ObservableDictionary(int capacity, IEqualityComparer comparer)
        {
            _Dictionary = new Dictionary(capacity, comparer);
            this._IndexDictionary = new Dictionary();
            this._BaseCollection = new List>();
        }
        #endregion

        #region IDictionary Members

        public void Add(TKey key, TValue value)
        {
            Insert(key, value, true);
        }

        public bool ContainsKey(TKey key)
        {
            return Dictionary.ContainsKey(key);
        }

        public ICollection 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)
            {
                int index = this._IndexDictionary[key];
                this._BaseCollection.RemoveAt(index);
                for (int x = index; x < this._BaseCollection.Count; x++)
                    this._IndexDictionary[this._BaseCollection[x].Key] = x;
                this._IndexDictionary.Remove(key);

                OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair(key, value), index);
            }
            return removed;
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            return _Dictionary.TryGetValue(key, out value);
        }

        public ICollection Values
        {
            get { return _Dictionary.Values; }
        }

        public TValue this[TKey key]
        {
            get
            {
                return _Dictionary[key];
            }
            set
            {
                Insert(key, value, false);
            }
        }

        #endregion

        #region ICollection> Members

        public void Add(KeyValuePair item)
        {
            Insert(item.Key, item.Value, true);
        }

        public void Clear()
        {
            if (_Dictionary.Count > 0)
            {
                _Dictionary.Clear();
                this._BaseCollection.Clear();
                this._IndexDictionary.Clear();
                OnCollectionChanged();
            }
        }

        public bool Contains(KeyValuePair item)
        {
            return Dictionary.Contains(item);
        }

        public void CopyTo(KeyValuePair[] 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 item)
        {
            return Remove(item.Key);
        }


        #endregion

        #region IEnumerable> Members

        public IEnumerator> GetEnumerator()
        {
            return Dictionary.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)Dictionary).GetEnumerator();
        }

        #endregion

        #region INotifyCollectionChanged Members

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public void AddRange(IDictionary 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);
                            this._BaseCollection.Add(item);
                            this._IndexDictionary[item.Key] = this._BaseCollection.Count - 1;
                        }
                }
                else
                {
                    _Dictionary = new Dictionary(items);
                    this._IndexDictionary.Clear();
                    this._BaseCollection.Clear();
                    foreach (var pair in items)
                    {
                        this._BaseCollection.Add(pair);
                        this._IndexDictionary[pair.Key] = this._BaseCollection.Count - 1;
                    }
                }

                OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray(), 0);
            }
        }

        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;
                this._BaseCollection[this._IndexDictionary[key]] = new KeyValuePair(key, value);

                OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair(key, value), new KeyValuePair(key, item), this._IndexDictionary[key]);
            }
            else
            {
                Dictionary[key] = value;
                this._BaseCollection.Add(new KeyValuePair(key, value));
                this._IndexDictionary[key] = this._BaseCollection.Count - 1;

                OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair(key, value), this._IndexDictionary[key]);
            }
        }

        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 NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair changedItem, int index)
        {
            OnPropertyChanged();
            if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem, index));
        }

        private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair newItem, KeyValuePair oldItem, int index)
        {
            OnPropertyChanged();
            if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index));
        }

        private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems, int index)
        {
            OnPropertyChanged();
            if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItems, index));
        }
    }

Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume