| File: MS\Internal\Annotations\ObservableDictionary.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // // Description: // ContentLocatorPart represents a set of name/value pairs that identify a // piece of data within a certain context. The names and values are // strings. // // Spec: Simplifying Store Cache Model.doc // using System.Collections; using System.ComponentModel; namespace MS.Internal.Annotations { /// <summary> /// ContentLocatorPart represents a set of name/value pairs that identify a /// piece of data within a certain context. The names and values are /// all strings. /// </summary> internal class ObservableDictionary : IDictionary<string, string>, INotifyPropertyChanged { //------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors /// <summary> /// Creates a ContentLocatorPart with the specified type name and namespace. /// </summary> public ObservableDictionary() { _nameValues = new Dictionary<string, string>(); } #endregion Constructors //------------------------------------------------------ // // Public Methods // //------------------------------------------------------ #region Public Methods /// <summary> /// Adds a key/value pair to the ContentLocatorPart. If a value for the key already /// exists, the old value is overwritten by the new value. /// </summary> /// <param name="key">key</param> /// <param name="val">value</param> /// <exception cref="ArgumentNullException">key or val is null</exception> /// <exception cref="ArgumentException">a value for key is already present in the locator part</exception> public void Add(string key, string val) { ArgumentNullException.ThrowIfNull(key); ArgumentNullException.ThrowIfNull(val); _nameValues.Add(key, val); FireDictionaryChanged(); } /// <summary> /// Removes all name/value pairs from the ContentLocatorPart. /// </summary> public void Clear() { int count = _nameValues.Count; if (count > 0) { _nameValues.Clear(); // Only fire changed event if the dictionary actually changed FireDictionaryChanged(); } } /// <summary> /// Returns whether or not a value of the key exists in this ContentLocatorPart. /// </summary> /// <param name="key">the key to check for</param> /// <returns>true - yes, false - no</returns> public bool ContainsKey(string key) { return _nameValues.ContainsKey(key); } /// <summary> /// Removes the key and its value from the ContentLocatorPart. /// </summary> /// <param name="key">key to be removed</param> /// <returns>true - the key was found in the ContentLocatorPart, false o- it wasn't</returns> public bool Remove(string key) { bool exists = _nameValues.Remove(key); // Only fire changed event if the key was actually removed if (exists) { FireDictionaryChanged(); } return exists; } /// <summary> /// Returns an enumerator for the key/value pairs in this ContentLocatorPart. /// </summary> /// <returns>an enumerator for the key/value pairs; never returns null</returns> IEnumerator IEnumerable.GetEnumerator() { return _nameValues.GetEnumerator(); } /// <summary> /// Returns an enumerator for the key/value pairs in this ContentLocatorPart. /// </summary> /// <returns>an enumerator for the key/value pairs; never returns null</returns> public IEnumerator<KeyValuePair<string, string>> GetEnumerator() { return ((IEnumerable<KeyValuePair<string, string>>)_nameValues).GetEnumerator(); } /// <summary> /// /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">key is null</exception> public bool TryGetValue(string key, out string value) { ArgumentNullException.ThrowIfNull(key); return _nameValues.TryGetValue(key, out value); } /// <summary> /// /// </summary> /// <param name="pair"></param> /// <exception cref="ArgumentNullException">pair is null</exception> void ICollection<KeyValuePair<string, string>>.Add(KeyValuePair<string, string> pair) { ((ICollection<KeyValuePair<string, string>>)_nameValues).Add(pair); } /// <summary> /// /// </summary> /// <param name="pair"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">pair is null</exception> bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> pair) { return ((ICollection<KeyValuePair<string, string>>)_nameValues).Contains(pair); } /// <summary> /// /// </summary> /// <param name="pair"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">pair is null</exception> bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> pair) { return ((ICollection<KeyValuePair<string, string>>)_nameValues).Remove(pair); } /// <summary> /// /// </summary> /// <param name="target"></param> /// <param name="startIndex"></param> /// <exception cref="ArgumentNullException">target is null</exception> /// <exception cref="ArgumentOutOfRangeException">startIndex is less than zero or greater than the lenght of target</exception> void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] target, int startIndex) { ArgumentNullException.ThrowIfNull(target); ArgumentOutOfRangeException.ThrowIfNegative(startIndex); ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, target.Length); ((ICollection<KeyValuePair<string, string>>)_nameValues).CopyTo(target, startIndex); } #endregion Public Methods //------------------------------------------------------ // // Public Operators // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties /// <summary> /// The number of name/value pairs in this ContentLocatorPart. /// </summary> /// <value>count of name/value pairs</value> public int Count { get { return _nameValues.Count; } } /// <summary> /// Indexer provides lookup of values by key. Gets or sets the value /// in the ContentLocatorPart for the specified key. If the key does not exist /// in the ContentLocatorPart, /// </summary> /// <param name="key">key</param> /// <returns>the value stored in this locator part for key</returns> public string this[string key] { get { ArgumentNullException.ThrowIfNull(key); string value = null; _nameValues.TryGetValue(key, out value); return value; } set { ArgumentNullException.ThrowIfNull(key); ArgumentNullException.ThrowIfNull(value); string oldValue = null; _nameValues.TryGetValue(key, out oldValue); // If the new value is actually different, then we add it and fire // a change notification if ((oldValue == null) || (oldValue != value)) { _nameValues[key] = value; FireDictionaryChanged(); } } } /// <summary> /// /// </summary> public bool IsReadOnly { get { return false; } } /// <summary> /// Returns a collection of all the keys in this ContentLocatorPart. /// </summary> /// <value>keys</value> public ICollection<string> Keys { get { return _nameValues.Keys; } } /// <summary> /// Returns a collection of all the values in this ContentLocatorPart. /// </summary> /// <value>values</value> public ICollection<string> Values { get { return _nameValues.Values; } } #endregion Public Properties //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ //------------------------------------------------------ // // Internal Operators // //------------------------------------------------------ //------------------------------------------------------ // // Internal Events // //------------------------------------------------------ #region Public Events /// <summary> /// /// </summary> public event PropertyChangedEventHandler PropertyChanged; #endregion Public Events //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods /// <summary> /// Notify the owner this ContentLocatorPart has changed. /// </summary> private void FireDictionaryChanged() { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(null)); } } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ #region Private Fields /// <summary> /// The internal data structure. /// </summary> private Dictionary<string, string> _nameValues; #endregion Private Fields } }