ObservableDictionary

Namespace: Catel.MVVM
We found 10 examples in language CSharp for this search. You will see 53 fragments of code.

        protected void SubscribeDirtyCollection<TKey, TValue>(ObservableDictionary<TKey, TValue> observableDictionary)
        {
            if (observableDictionary == null)
            {
                return;
            }

            observableDictionary.CollectionChanged += DirtyDictionary_CollectionChanged<TKey, TValue>;
            SubscribeCollectionItems(observableDictionary.Values.OfType<DirtyBase>());
        }

        protected void UnsubscribeDirtyCollection<TKey, TValue>(ObservableDictionary<TKey, TValue> observableDictionary)
        {
            if (observableDictionary == null)
            {
                return;
            }

            observableDictionary.CollectionChanged -= DirtyDictionary_CollectionChanged<TKey, TValue>;
            UnsubscribeCollectionItems(observableDictionary.Values.OfType<DirtyBase>());
        }


    /// <summary>
    ///   指定された引数を使用して、
    ///   <see cref="E:System.Collections.Generic.ObservableDictionary`2.PropertyChanged" /> イベントを発生させます。
    /// </summary>
    /// <param name="propertyName">変更されたプロパティの名前。</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    }

    /// <summary>
    ///   指定された引数を使用して、
    ///   <see cref="E:System.Collections.Generic.ObservableDictionary`2.CollectionChanged" /> イベントを発生させます。
    /// </summary>
    /// <param name="e">発生させるイベントの引数。</param>
    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
      if (CollectionChanged != null)
      {
        CollectionChanged(this, e);
      }
    }

    private void OnCollectionAdded(KeyValuePair<TKey, TValue> changedItem, int startingIndex)
    {
      OnPropertyChanged(DictionaryName);
      OnPropertyChanged(ItemsName);
      OnPropertyChanged(CountName);
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItem, startingIndex));
    }

    private void OnCollectionRemoved(KeyValuePair<TKey, TValue> changedItem, int startingIndex)
    {
      OnPropertyChanged(DictionaryName);
      OnPropertyChanged(ItemsName);
      OnPropertyChanged(KeysName);
      OnPropertyChanged(ValuesName);
      OnPropertyChanged(CountName);
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItem, startingIndex));
    }

    private void OnCollectionMoved(KeyValuePair<TKey, TValue> changedItem, int index, int oldIndex)
    {
      OnPropertyChanged(DictionaryName);
      OnPropertyChanged(ItemsName);
      OnPropertyChanged(KeysName);
      OnPropertyChanged(ValuesName);
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, changedItem, index, oldIndex));
    }

    private void OnCollectionReplaced(KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
    {
      OnPropertyChanged(DictionaryName);
      OnPropertyChanged(ItemsName);
      OnPropertyChanged(KeysName);
      OnPropertyChanged(ValuesName);
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, oldItem));
    }


        /// <summary>
        /// Register a callback to be fired when an action occurs
        /// </summary>
        /// <param name="action">The action</param>
        /// <param name="callback">The callback to fire</param>
        public void AddDelegate(DictionaryEventAction action, DictionaryChangeCallback callback)
        {
            if (Delegates.ContainsKey(action))
            {
                Delegates[action].Add(callback);   
            }
            else
            {
                List<DictionaryChangeCallback> callbacks = new List<DictionaryChangeCallback>(1);
                callbacks.Add(callback);
                Delegates.Add(action, callbacks);
            }
        }

        /// <summary>
        /// Unregister a callback
        /// </summary>
        /// <param name="action">The action</param>
        /// <param name="callback">The callback to fire</param>
        public void RemoveDelegate(DictionaryEventAction action, DictionaryChangeCallback callback)
        {
            if (Delegates.ContainsKey(action))
            {
                if (Delegates[action].Contains(callback))
                    Delegates[action].Remove(callback);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <param name="entry"></param>
        private void FireChangeEvent(DictionaryEventAction action, DictionaryEntry entry)
        {
            
            if(Delegates.ContainsKey(action))
            {
                foreach(DictionaryChangeCallback handler in Delegates[action])
                {
                    handler(action, entry);
                }
            }
        }

        /// <summary>
        /// Try to get entry from the <seealso cref="ObservableDictionary"/> with specified key 
        /// </summary>
        /// <param name="key">Key to use for lookup</param>
        /// <param name="value">Value returned</param>
        /// <returns><see langword="true"/> if specified key exists,  <see langword="false"/> if not found</returns>
        /// <example>
        /// <code>
        /// // find your avatar using the Simulator.ObjectsAvatars ObservableDictionary:
        ///    Avatar av;
        ///    if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av))
        ///        Console.WriteLine("Found Avatar {0}", av.Name);
        /// </code>
        /// <seealso cref="Simulator.ObjectsAvatars"/>
        /// </example>
        public bool TryGetValue(TKey key, out TValue value)
        {
                return Dictionary.TryGetValue(key, out value);
        }

        /// <summary>
        /// Finds the specified match.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <returns>Matched value</returns>
        /// <example>
        /// <code>
        /// // use a delegate to find a prim in the ObjectsPrimitives ObservableDictionary
        /// // with the ID 95683496
        /// uint findID = 95683496;
        /// Primitive findPrim = sim.ObjectsPrimitives.Find(
        ///             delegate(Primitive prim) { return prim.ID == findID; });
        /// </code>
        /// </example>
        public TValue Find(Predicate<TValue> match)
        {
                foreach (TValue value in Dictionary.Values)
                {
                    if (match(value))
                        return value;
                }
            return default(TValue);
        }

        /// <summary>Find All items in an <seealso cref="T:ObservableDictionary"/></summary>
        /// <param name="match">return matching items.</param>
        /// <returns>a <seealso cref="T:System.Collections.Generic.List"/> containing found items.</returns>
        /// <example>
        /// Find All prims within 20 meters and store them in a List
        /// <code>
        /// int radius = 20;
        /// List&lt;Primitive&gt; prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
        ///         delegate(Primitive prim) {
        ///             Vector3 pos = prim.Position;
        ///             return ((prim.ParentID == 0) &amp;&amp; (pos != Vector3.Zero) &amp;&amp; (Vector3.Distance(pos, location) &lt; radius));
        ///         }
        ///    ); 
        ///</code>
        ///</example>
        public List<TValue> FindAll(Predicate<TValue> match)
        {
            List<TValue> found = new List<TValue>();
         
                foreach (KeyValuePair<TKey, TValue> kvp in Dictionary)
                {
                    if (match(kvp.Value))
                        found.Add(kvp.Value);
                }
                     return found;
        }

		#endregion

		#region Event handler
		/// <summary>
		/// <para>CellClick-Event of <see cref="dgvPlugins"/></para>
		/// <para>Update the <see cref="plugins"/> dictionary and refresh the <see cref="DataGridView"/></para>
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void dgvPlugins_CellClick(object sender, DataGridViewCellEventArgs e)
		{
			if (e.ColumnIndex != 1 || e.RowIndex < 0)		// Only first column
				return;

			plugins[e.RowIndex] = !plugins[e.RowIndex];		// Toggle enabled value of plugin. Why does the BindingSource not do this?
			this.pluginBinding.DataSource = null;			// TODO: BindingSource does not register for OnCollectionChanged!?
			this.pluginBinding.DataSource = plugins;
		}

		/// <summary>
		/// <para>FormClosing-Event of <see cref="TaskOptions"/></para>
		/// <para>Save the plugin settings and notify the <see cref="TaskManager"/></para>
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void TaskOptions_FormClosing(object sender, FormClosingEventArgs e)
		{
			PutPluginsSetting(plugins);

			this.Hide();
			this.Main.TaskMgr.Refresh(plugins);
		}
		#endregion

		#region Methods
		/// <summary>
		/// <para>Fetches the settings and convert them to a <see cref="ObservableDictionary<string, bool>"/></para>
		/// </summary>
		/// <returns></returns>
		public static ObservableDictionary<string, bool> GetPluginsSetting()
		{
			ObservableDictionary<string, bool> setting;
			if (String.IsNullOrEmpty(Properties.Settings.Default.PluginsEnabled))
				setting = new ObservableDictionary<string, bool>();
			else
			{
				XmlSerializer xmlSer = new XmlSerializer(typeof(ObservableDictionary<string, bool>));
				setting = (ObservableDictionary<string, bool>)xmlSer.Deserialize(new StringReader(Properties.Settings.Default.PluginsEnabled));
			}
			return setting;
		}

		/// <summary>
		/// <para>Saves the <see cref="ObservableDictionary<string, bool>"/> in the settings</para>
		/// </summary>
		/// <param name="plugins"></param>
		public static void PutPluginsSetting(ObservableDictionary<string, bool> plugins)
		{
			StringBuilder str = new StringBuilder();
			XmlSerializer xmlSer = new XmlSerializer(typeof(ObservableDictionary<string, bool>));
			xmlSer.Serialize(new StringWriter(str), plugins);
			Properties.Settings.Default.PluginsEnabled = str.ToString();
			Properties.Settings.Default.Save();
		}

		/// <summary>
		/// <para>Creates a <see cref="ObservableDictionary<string, bool>"/> that contains all available <see cref="TaskPlugin"/>s and loads their values from the settings</para>
		/// </summary>
		/// <param name="Main"></param>
		/// <returns></returns>
		public static ObservableDictionary<string, bool> GetPluginsAll(Main Main)
		{
			ObservableDictionary<string, bool> setting = GetPluginsSetting();

			ObservableDictionary<string, bool> plugins = new ObservableDictionary<string, bool>();
			foreach (Type task in Main.TaskMgr.TaskPluginsAvailable)
			{
				string name = task.Name;
				bool enabled = true;
				if (setting.ContainsKey(name))
					enabled = setting[name];
				plugins.Add(name, enabled);
			}

			return plugins;
		}


    public override IDeepCloneable Clone(Cloner cloner) {
      return new Run(this, cloner);
    }

    private void Initialize(IAlgorithm algorithm) {
      parameters = new ObservableDictionary<string, IItem>();
      results = new ObservableDictionary<string, IItem>();

      if (algorithm.StoreAlgorithmInEachRun) {
        var clone = (IAlgorithm)algorithm.Clone();
        clone.CollectParameterValues(parameters);
        clone.CollectResultValues(results);
        clone.Runs.Clear();
        this.algorithm = clone;
      } else {
        var par = new Dictionary<string, IItem>();
        var res = new Dictionary<string, IItem>();
        algorithm.CollectParameterValues(par);
        algorithm.CollectResultValues(res);
        var cloner = new Cloner();
        foreach (var k in par) parameters.Add(k.Key, cloner.Clone(k.Value));
        foreach (var k in res) results.Add(k.Key, cloner.Clone(k.Value));
      }
    }
    [StorableHook(HookType.AfterDeserialization)]
    private void AfterDeserialization() {
      if (color == Color.Empty) color = Color.Black;
    }
    private void OnPropertyChanged(string property) {
      var handler = PropertyChanged;
      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
    }


        #endregion


        #region 公共方法定义

        /// <summary>
        /// 确定 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 是否包含特定值。
        /// </summary>
        /// <param name="value">要在 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中定位的值。 对于引用类型,该值可以为 null。</param>
        /// <returns>如果 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 包含具有指定值的元素,则为 true;否则为 false。</returns>
        public bool ContainsValue(TValue value)
        {
            return this.Dictionary.ContainsValue(value);
        }

        #endregion


        #region IDictionary 接口方法实现

        /// <summary>
        /// 在 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中添加一个带有所提供的键和值的元素。
        /// <para>该操作将会引发 Action 为 <seealso cref="NotifyCollectionChangedAction.Add"/> 的 CollectionChanged 事件 和 PropertyChanged 事件。</para>
        /// </summary>
        /// <param name="key">被添加的元素的键。</param>
        /// <param name="value">被添加的元素的值。</param>
        /// <exception cref="System.ArgumentNullException"><paramref name="key"/> 为 null</exception>
        /// <exception cref="System.ArgumentException"><see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中已存在具有相同键的元素。</exception>
        public void Add(TKey key, TValue value)
        {
            this.AddOrUpdate(key, value, true);
        }

        /// <summary>
        /// 从 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中移除带有指定键的元素。
        /// <para>该操作成功时将会引发 Action 为 <seealso cref="NotifyCollectionChangedAction.Remove"/> 的 CollectionChanged 事件 和 PropertyChanged 事件。</para>
        /// </summary>
        /// <param name="key">要移除的元素的键。</param>
        /// <returns>如果该元素已成功移除,则为 true;否则为 false。 如果在原始 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中没有找到 <paramref name="key"/>,此方法也会返回 false。</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="key"/> 为 null</exception>
        public bool Remove(TKey key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            TValue value;
            this.Dictionary.TryGetValue(key, out value);
            bool removed = this.Dictionary.Remove(key);
            if (removed)
            {
                var item = new KeyValuePair<TKey, TValue>(key, value);
                this.OnCollectionRemove(item);
            }

            return removed;
        }

        /// <summary>
        /// 获取与指定的键相关联的值。
        /// </summary>
        /// <param name="key">要获取的值的键。</param>
        /// <param name="value">当此方法返回值时,如果找到该键,便会返回与指定的键相关联的值;否则,则会返回 value 参数的类型默认值。 该参数未经初始化即被传递。</param>
        /// <returns>如果 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 包含具有指定键的元素,则为 true;否则为 false。</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="key"/> 为 null。</exception>
        public bool TryGetValue(TKey key, out TValue value)
        {
            return this.Dictionary.TryGetValue(key, out value);
        }

        /// <summary>
        /// 从 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中移除所有的键和值。
        /// <para>该操作将会引发 Action 为 <seealso cref="NotifyCollectionChangedAction.Reset"/> 的 CollectionChanged 事件 和 PropertyChanged 事件。</para>
        /// </summary>
        public void Clear()
        {
            if (this.Dictionary.Count > 0)
            {
                List<KeyValuePair<TKey, TValue>> items = this.Dictionary.ToList();
                this.Dictionary.Clear();
                this.OnCollectionReset(items);
            }
        }

        /// <summary>
        /// 确定 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 是否包含指定的键。
        /// </summary>
        /// <param name="key">要在 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 中定位的键。</param>
        /// <returns>如果 <see cref="ObservableDictionary&lt;TKey, TValue&gt;"/> 包含具有指定键的元素,则为 true;否则为 false。</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="key"/> 为 null。</exception>
        public bool ContainsKey(TKey key)
        {
            return this.Dictionary.ContainsKey(key);
        }


		public new void Add(TKey key, TValue value) {
			if (!base.ContainsKey(key)) {
				var item = new KeyValuePair<TKey, TValue>(key, value);
				base.Add(key, value);
				this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, base.Keys.ToList().IndexOf(key)));
				this.OnPropertyChanged(nameof(Count));
			}
		}

		public new bool Remove(TKey key) {
			TValue value;
			if (base.TryGetValue(key, out value)) {
				var item = new KeyValuePair<TKey, TValue>(key, base[key]);
				bool result = base.Remove(key);
				this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, base.Keys.ToList().IndexOf(key)));
				this.OnPropertyChanged(nameof(Count));
				return result;
			}
			return false;
		}

		public new void Clear() {
			base.Clear();
			this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
			this.OnPropertyChanged(nameof(Count));
		}

		protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
			CollectionChanged?.Invoke(this, e);
		}

		protected void OnPropertyChanged(PropertyChangedEventArgs e) {
			PropertyChanged?.Invoke(this, e);
		}
		protected void OnPropertyChanged(string propertyName) {
			OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
		}


        public override string ToString() => PropertyName;

        /// <summary>
        /// Gets the value of the property with the specified name from the specified object.
        /// </summary>
        /// <typeparam name="T">The type of the property value to retrieve.</typeparam>
        /// <param name="obj">The object from which to retrieve the property value.</param>
        /// <returns></returns>
        public T GetValue<T>(object obj)
        {
            return (T)obj.GetType().GetProperty(PropertyName)?.GetValue(obj);
        }

        /// <summary>
        /// Gets the property info for the specified object.
        /// </summary>
        /// <param name="obj">The object from which to retrieve the property.</param>
        /// <returns></returns>
        public PropertyInfo GetProperty(object obj)
        {
            return obj.GetType().GetProperty(PropertyName);
        }

        /// <summary>
        /// Add a range of items to the collection.
        /// </summary>
        /// <param name="items">The items to add.</param>
        public void AddRange(IEnumerable<TValue> items)
        {
            lock (lockObject)
            {
                var oldno = noevent;
                noevent = true;

                foreach (var item in items)
                {
                    Add(item);
                }

                noevent = oldno;
                if (!noevent) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            }
        }

        /// <summary>
        /// Try to get the value with the specified key.
        /// </summary>
        /// <param name="key">The key to search for.</param>
        /// <param name="value">Receives the item that was found, or null/default.</param>
        /// <returns>True if the item was found.</returns>
#if DOTNETSTD
        public bool TryGetValue(TKey key, out TValue value)
#else
        public bool TryGetValue(TKey key, out TValue value)
#endif
        {
            if (!Contains(key))
            {
                value = default;
                return false;
            }
            else
            {
                value = ((IDictionary<TKey, TValue>)this)[key];
                return true;
            }

        }

        /// <summary>
        /// Return the contents of this collection as an array of <see cref="T"/>.
        /// </summary>
        /// <returns></returns>
        public TValue[] ToArray()
        {
            lock (lockObject)
            {
                if (Count == 0) return new TValue[0];
                TValue[] output = new TValue[Count];

                CopyTo(output, 0);
                return output;
            }
        }


        /// <summary>
        ///     Adds an item to the dictionary.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void Add(
            TKey key,
            TValue value)
        {
            // PRECONDITIONS

            // Current object not disposed
            this.RequiresNotDisposed();

            // ACTION

            // Under write lock
            using (this.WriteLock())
            {
                // Add the item
                var newIndex = this.InternalContainer.Add(
                    key,
                    value);

                // Push the undo level
                this.PushUndoLevel(
                    new AddUndoLevel<KeyValuePair<TKey, TValue>>
                    {
                        AddedItem = new KeyValuePair<TKey, TValue>(
                            key,
                            value),
                        Index = newIndex
                    });
            }

            // NOTIFICATIONS
            this.BroadcastChange();
        }

        /// <summary>
        ///     Determines whether the dictionary contains a specific key.
        /// </summary>
        /// <param name="key">The key to look for.</param>
        /// <returns><see langword="true" /> whether a key has been found, <see langword="false" /> otherwise.</returns>
        public bool ContainsKey(TKey key)
        {
            this.RequiresNotDisposed();

            using (this.ReadLock())
            {
                return this.InternalContainer.ContainsKey(key);
            }
        }

        /// <summary>
        ///     Attempts to remove all info related to a key from the dictionary.
        /// </summary>
        /// <param name="key">The key to remove data from.</param>
        /// <returns><see langword="true" /> if the removal was successful, <see langword="false" /> otherwise.</returns>
        public bool Remove(TKey key)
        {
            // PRECONDITIONS

            // Current object not disposed
            this.RequiresNotDisposed();

            // ACTION
            bool result;
            IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

            // Within a read/write lock
            using (ReadWriteSynchronizationLocker locker = this.ReadWriteLock())
            {
                // Find out if there's anything to remove
                if (!container.TryGetValue(
                    key,
                    out TValue value))
                {
                    return false;
                }

                // Upgrade the locker to a write lock
                locker.Upgrade();

                // Do the actual removal
                result = container.Remove(key);

                // Push undo level
                if (result)
                {
                    this.PushUndoLevel(new DictionaryRemoveUndoLevel<TKey, TValue> { Key = key, Value = value });
                }
            }

            // NOTIFICATION AND RETURN
            if (result)
            {
                this.BroadcastChange();
            }

            return result;
        }

        /// <summary>
        ///     Attempts to fetch a value for a specific key, indicating whether it has been found or not.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns><see langword="true" /> if the value was successfully fetched, <see langword="false" /> otherwise.</returns>
        public bool TryGetValue(
            TKey key,
            out TValue value)
        {
            this.RequiresNotDisposed();

            using (this.ReadLock())
            {
                return this.InternalContainer.TryGetValue(
                    key,
                    out value);
            }
        }

        /// <summary>
        ///     Called when contents of this dictionary may have changed.
        /// </summary>
        protected override void ContentsMayHaveChanged()
        {
            this.RaisePropertyChanged(nameof(this.Keys));
            this.RaisePropertyChanged(nameof(this.Values));
            this.RaisePropertyChanged(Constants.ItemsName);
        }

        #region Undo/Redo

        /// <summary>
        ///     Has the last operation undone.
        /// </summary>
        /// <param name="undoRedoLevel">A level of undo, with contents.</param>
        /// <param name="toInvokeOutsideLock">An action to invoke outside of the lock.</param>
        /// <param name="state">The state object to pass to the invocation.</param>
        /// <returns><see langword="true" /> if the undo was successful, <see langword="false" /> otherwise.</returns>
        protected override bool UndoInternally(
            StateChange undoRedoLevel,
            out Action<object> toInvokeOutsideLock,
            out object state)
        {
            if (base.UndoInternally(
                undoRedoLevel,
                out toInvokeOutsideLock,
                out state))
            {
                return true;
            }

            switch (undoRedoLevel)
            {
                case AddUndoLevel<KeyValuePair<TKey, TValue>> aul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    container.Remove(aul.AddedItem.Key);

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                case RemoveUndoLevel<KeyValuePair<TKey, TValue>> rul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    container.Add(
                        rul.RemovedItem.Key,
                        rul.RemovedItem.Value);

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                case ClearUndoLevel<KeyValuePair<TKey, TValue>> cul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    foreach (KeyValuePair<TKey, TValue> item in cul.OriginalItems)
                    {
                        container.Add(
                            item.Key,
                            item.Value);
                    }

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                case DictionaryAddUndoLevel<TKey, TValue> daul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    container.Remove(daul.Key);

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                case DictionaryRemoveUndoLevel<TKey, TValue> raul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    container.Add(
                        raul.Key,
                        raul.Value);

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                case DictionaryChangeUndoLevel<TKey, TValue> caul:
                {
                    IDictionaryCollectionAdapter<TKey, TValue> container = this.InternalContainer;

                    container[caul.Key] = caul.OldValue;

                    toInvokeOutsideLock = innerState =>
                        ((ObservableDictionary<TKey, TValue>)innerState).BroadcastChange();
                    state = this;

                    break;
                }

                default:
                {
                    toInvokeOutsideLock = null;
                    state = null;

                    return false;
                }
            }

            return true;
        }

		#endregion

		#region Methods - IDictionary Members
		/// <summary>
		/// Adds the specified key/value pair to the dictionary.
		/// </summary>
		/// <param name="item">The key/value pair to add.</param>
		public void Add(KeyValuePair<TKey, TValue> item)
		{
			this.Dictionary.Add(item);
			this.ValueCollection.Add(item.Value);
			this.OnCollectionChanged(NotifyCollectionChangedAction.Add, item);
		}

		/// <summary>
		/// Adds the specified key and value to the dictionary.
		/// </summary>
		/// <param name="key">The key of the element to add.</param>
		/// <param name="value">The value of the element to add. The value can be null for reference types.</param>
		public void Add(TKey key, TValue value)
		{
			var item = new KeyValuePair<TKey, TValue>(key, value);

			this.Dictionary.Add(item);
            this.ValueCollection.Add(value);
			this.OnCollectionChanged(NotifyCollectionChangedAction.Add, item);
		}

		/// <summary>
		/// Removes all keys and values from the <see cref="ObservableDictionary{TKey, TValue}"/>.
		/// </summary>
		public void Clear()
		{
			if (this.Dictionary.Count > 0)
			{
				this.Dictionary.Clear();
				this.OnCollectionChanged();
			}
			this.ValueCollection.Clear();
		}

		/// <summary>
		/// Determines whether the <see cref="ObservableDictionary{TKey, TValue}"/> contains a specific value.
		/// </summary>
		/// <param name="item">The key/value pair to find.</param>
		/// <returns>
		/// Returns true if the key/value pair is found, otherwise false.
		/// </returns>
		public bool Contains(KeyValuePair<TKey, TValue> item)
		{
			return this.Dictionary.Contains(item);
		}

		/// <summary>
		/// Determines whether the <see cref="ObservableDictionary{TKey, TValue}"/> contains the specified key.
		/// </summary>
		/// <param name="key">
		/// The key to locate in the <see cref="ObservableDictionary{TKey, TValue}"/>.
		/// </param>
		/// <returns>
		/// Returns true if the <see cref="ObservableDictionary{TKey, TValue}"/>
		/// contains an element with the specified key, otherwise false.
		/// </returns>
		public bool ContainsKey(TKey key)
		{
			return this.Dictionary.ContainsKey(key);
		}

		/// <summary>
		/// Copies the elements of the <see cref="ObservableDictionary{TKey, TValue}"/>
		/// to an <see cref="Array"/>, starting at a particular index.
		/// </summary>
		/// <param name="array">
		/// The one-dimensional array that is the destination of the elements copied
		/// from <see cref="ObservableDictionary{TKey, TValue}"/>. The array must have
		/// zero-based indexing.
		/// </param>
		/// <param name="arrayIndex">
		/// The zero-based index in array at which copying begins.
		/// </param>
		public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
		{
			this.Dictionary.CopyTo(array, arrayIndex);
		}

Catel.Collections.ObservableDictionary<TKey, TValue> : IDictionary

Constructors :

public ObservableDictionary()
public ObservableDictionary(IEqualityComparer<TKey> comparer = )
public ObservableDictionary(IDictionary<TKey, TValue> dictionary = )
public ObservableDictionary(IDictionary<TKey, TValue> dictionary = , IEqualityComparer<TKey> comparer = )

Methods :

public Boolean get_AutomaticallyDispatchChangeNotifications()
public Void set_AutomaticallyDispatchChangeNotifications(Boolean value = )
public IEqualityComparer<TKey> get_Comparer()
public FastObservableDictionary<TKey, TValue> AsReadOnly()
public IEnumerable<KeyValuePair<TKey, TValue>> AsEnumerable()
public Void InsertSingleValue(TKey key = , TValue newValue = , Boolean checkKeyDuplication = )
public Void InsertSingleValue(Int32 index = , TKey key = , TValue newValue = , Boolean checkKeyDuplication = )
public Void MoveItem(Int32 oldIndex = , Int32 newIndex = )
public Boolean TryRemoveSingleValue(TKey keyToRemove = , TValue& value = )
public Void RemoveSingleValue(Int32 index = , TValue& value = )
public Void InsertMultipleValues(IEnumerable<KeyValuePair<TKey, TValue>> newValues = , Boolean checkKeyDuplication = )
public Void InsertMultipleValues(Int32 startIndex = , IEnumerable<KeyValuePair<TKey, TValue>> newValues = , Boolean checkKeyDuplication = )
public Void RemoveMultipleValues(Int32 startIndex = , Int32 count = )
public Void RemoveMultipleValues(IEnumerable<TKey> keysToRemove = )
public Void RemoveAllItems()
public Int32 get_Count()
public Boolean get_IsReadOnly()
public Void Add(KeyValuePair<TKey, TValue> item = )
public Void Clear()
public Boolean Contains(KeyValuePair<TKey, TValue> item = )
public Void CopyTo(KeyValuePair array = , Int32 arrayIndex = )
public Boolean Remove(KeyValuePair<TKey, TValue> item = )
public TValue get_Item(TKey key = )
public Void set_Item(TKey key = , TValue value = )
public ICollection<TKey> get_Keys()
public ICollection<TValue> get_Values()
public Boolean ContainsKey(TKey key = )
public Void Add(TKey key = , TValue value = )
public Boolean Remove(TKey keyToRemove = )
public Boolean TryGetValue(TKey key = , TValue& value = )
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
public Boolean get_IsFixedSize()
public Object get_SyncRoot()
public Boolean get_IsSynchronized()
public Object get_Item(Object key = )
public Void set_Item(Object key = , Object value = )
public Boolean Contains(Object key = )
public Void Add(Object key = , Object value = )
public Void CopyTo(Array array = , Int32 arrayIndex = )
public Int32 IndexOf(KeyValuePair<TKey, TValue> item = )
public Void Insert(Int32 index = , KeyValuePair<TKey, TValue> item = )
public Void RemoveAt(Int32 index = )
public Void GetObjectData(SerializationInfo info = , StreamingContext context = )
public Void OnDeserialization(Object sender = )
public Void add_CollectionChanged(NotifyCollectionChangedEventHandler value = )
public Void remove_CollectionChanged(NotifyCollectionChangedEventHandler value = )
public Void add_PropertyChanged(PropertyChangedEventHandler value = )
public Void remove_PropertyChanged(PropertyChangedEventHandler value = )
public Void Reset()
public IDisposable SuspendChangeNotifications()
public IDisposable SuspendChangeNotifications(SuspensionMode mode = )
public Boolean get_IsDirty()
public Boolean get_NotificationsSuspended()
public Type GetType()
public String ToString()
public Boolean Equals(Object obj = )
public Int32 GetHashCode()