Social Icons

lunes, 10 de diciembre de 2012

ObservableDictionary para Silverlight

He reutilizado copiado el código del Blog de Shimmy pero he tenido que modificarlo un poco para que encajase en Silverlight. De momento solo lo he usado en uno de mis proyectos pero funciona bastante bien.

  1. using System;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using System.Collections.Specialized;  
  5. using System.ComponentModel;  
  6. using System.Linq;  
  7.   
  8. namespace SLUtils.Classes  
  9. {  
  10.         public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged  
  11.         {  
  12.             private const string CountString = "Count";  
  13.             private const string IndexerName = "Item[]";  
  14.             private const string KeysName = "Keys";  
  15.             private const string ValuesName = "Values";  
  16.   
  17.             private IDictionary<TKey, TValue> _Dictionary;  
  18.             protected IDictionary<TKey, TValue> Dictionary  
  19.             {  
  20.                 get { return _Dictionary; }  
  21.             }  
  22.  
  23.             #region Constructors  
  24.             public ObservableDictionary()  
  25.             {  
  26.                 _Dictionary = new Dictionary<TKey, TValue>();  
  27.             }  
  28.             public ObservableDictionary(IDictionary<TKey, TValue> dictionary)  
  29.             {  
  30.                 _Dictionary = new Dictionary<TKey, TValue>(dictionary);  
  31.             }  
  32.             public ObservableDictionary(IEqualityComparer<TKey> comparer)  
  33.             {  
  34.                 _Dictionary = new Dictionary<TKey, TValue>(comparer);  
  35.             }  
  36.             public ObservableDictionary(int capacity)  
  37.             {  
  38.                 _Dictionary = new Dictionary<TKey, TValue>(capacity);  
  39.             }  
  40.             public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)  
  41.             {  
  42.                 _Dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);  
  43.             }  
  44.             public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)  
  45.             {  
  46.                 _Dictionary = new Dictionary<TKey, TValue>(capacity, comparer);  
  47.             }  
  48.             #endregion  
  49.  
  50.             #region IDictionary<TKey,TValue> Members  
  51.   
  52.             public void Add(TKey key, TValue value)  
  53.             {  
  54.                 Insert(key, value, true);  
  55.             }  
  56.   
  57.             public bool ContainsKey(TKey key)  
  58.             {  
  59.                 return Dictionary.ContainsKey(key);  
  60.             }  
  61.   
  62.             public ICollection<TKey> Keys  
  63.             {  
  64.                 get { return Dictionary.Keys; }  
  65.             }  
  66.   
  67.             public bool Remove(TKey key)  
  68.             {  
  69.                 if (key == nullthrow new ArgumentNullException("key");  
  70.   
  71.                 TValue value;  
  72.                 Dictionary.TryGetValue(key, out value);  
  73.   
  74.                 int index = GetIndex(Dictionary, key);  
  75.                 var removed = Dictionary.Remove(key);  
  76.   
  77.                 if (removed)  
  78.                     OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value), index);  
  79.                     //OnCollectionChanged();  
  80.                 return removed;  
  81.             }  
  82.   
  83.             public bool TryGetValue(TKey key, out TValue value)  
  84.             {  
  85.                 return Dictionary.TryGetValue(key, out value);  
  86.             }  
  87.   
  88.             public ICollection<TValue> Values  
  89.             {  
  90.                 get { return Dictionary.Values; }  
  91.             }  
  92.   
  93.             public TValue this[TKey key]  
  94.             {  
  95.                 get  
  96.                 {  
  97.                     return Dictionary[key];  
  98.                 }  
  99.                 set  
  100.                 {  
  101.                     Insert(key, value, false);  
  102.                 }  
  103.             }  
  104.  
  105.             #endregion  
  106.  
  107.             #region ICollection<KeyValuePair<TKey,TValue>> Members  
  108.   
  109.             public void Add(KeyValuePair<TKey, TValue> item)  
  110.             {  
  111.                 Insert(item.Key, item.Value, true);  
  112.             }  
  113.   
  114.             public void Clear()  
  115.             {  
  116.                 if (Dictionary.Count > 0)  
  117.                 {  
  118.                     Dictionary.Clear();  
  119.                     OnCollectionChanged();  
  120.                 }  
  121.             }  
  122.   
  123.             public bool Contains(KeyValuePair<TKey, TValue> item)  
  124.             {  
  125.                 return Dictionary.Contains(item);  
  126.             }  
  127.   
  128.             public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)  
  129.             {  
  130.                 Dictionary.CopyTo(array, arrayIndex);  
  131.             }  
  132.   
  133.             public int Count  
  134.             {  
  135.                 get { return Dictionary.Count; }  
  136.             }  
  137.   
  138.             public bool IsReadOnly  
  139.             {  
  140.                 get { return Dictionary.IsReadOnly; }  
  141.             }  
  142.   
  143.             public bool Remove(KeyValuePair<TKey, TValue> item)  
  144.             {  
  145.                 return Remove(item.Key);  
  146.             }  
  147.  
  148.             #endregion  
  149.  
  150.             #region IEnumerable<KeyValuePair<TKey,TValue>> Members  
  151.   
  152.             public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()  
  153.             {  
  154.                 return Dictionary.GetEnumerator();  
  155.             }  
  156.  
  157.             #endregion  
  158.  
  159.             #region IEnumerable Members  
  160.   
  161.             IEnumerator IEnumerable.GetEnumerator()  
  162.             {  
  163.                 return ((IEnumerable)Dictionary).GetEnumerator();  
  164.             }  
  165.  
  166.             #endregion  
  167.  
  168.             #region INotifyCollectionChanged Members  
  169.   
  170.             public event NotifyCollectionChangedEventHandler CollectionChanged;  
  171.  
  172.             #endregion  
  173.  
  174.             #region INotifyPropertyChanged Members  
  175.   
  176.             public event PropertyChangedEventHandler PropertyChanged;  
  177.  
  178.             #endregion  
  179.   
  180.             public void AddRange(IDictionary<TKey, TValue> items)  
  181.             {  
  182.                 if (items == nullthrow new ArgumentNullException("items");  
  183.   
  184.                 if (items.Count > 0)  
  185.                 {  
  186.                     if (Dictionary.Count > 0)  
  187.                     {  
  188.                         if (items.Keys.Any((k) => Dictionary.ContainsKey(k)))  
  189.                             throw new ArgumentException("An item with the same key has already been added.");  
  190.                         else  
  191.                             foreach (var item in items) Dictionary.Add(item);  
  192.                     }  
  193.                     else  
  194.                         _Dictionary = new Dictionary<TKey, TValue>(items);  
  195.   
  196.                     OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray(), GetIndex(Dictionary, items.Keys.First())); //We notify the index of the first added key  
  197.                 }  
  198.             }  
  199.   
  200.             private void Insert(TKey key, TValue value, bool add)  
  201.             {  
  202.                 if (key == nullthrow new ArgumentNullException("key");  
  203.   
  204.                 TValue item;  
  205.                 if (Dictionary.TryGetValue(key, out item))  
  206.                 {  
  207.                     if (add) throw new ArgumentException("An item with the same key has already been added.");  
  208.                     if (Equals(item, value)) return;  
  209.                     Dictionary[key] = value;  
  210.   
  211.                     OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item), GetIndex(Dictionary, key));  
  212.                 }  
  213.                 else  
  214.                 {  
  215.                     Dictionary[key] = value;  
  216.   
  217.                     OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value), GetIndex(Dictionary, key));  
  218.                 }  
  219.             }  
  220.   
  221.             private void OnPropertyChanged()  
  222.             {  
  223.                 OnPropertyChanged(CountString);  
  224.                 OnPropertyChanged(IndexerName);  
  225.                 OnPropertyChanged(KeysName);  
  226.                 OnPropertyChanged(ValuesName);  
  227.             }  
  228.   
  229.             private int GetIndex(IDictionary<TKey, TValue> Dictionary, TKey key)  
  230.             {  
  231.                 int i = 0;  
  232.                 foreach (var dictKey in Dictionary.Keys)  
  233.                 {  
  234.                     if (dictKey.Equals(key)) return i;  
  235.                 }  
  236.   
  237.                 return -1;  
  238.             }  
  239.   
  240.             protected virtual void OnPropertyChanged(string propertyName)  
  241.             {  
  242.                 if (PropertyChanged != null) PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  243.             }  
  244.   
  245.             private void OnCollectionChanged()  
  246.             {  
  247.                 OnPropertyChanged();  
  248.                 if (CollectionChanged != null) CollectionChanged(thisnew NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));  
  249.             }  
  250.   
  251.             private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem, int index)  
  252.             {  
  253.                 OnPropertyChanged();  
  254.                 if (CollectionChanged != null) CollectionChanged(thisnew NotifyCollectionChangedEventArgs(action, changedItem, index));  
  255.             }  
  256.   
  257.             private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem, int index)  
  258.             {  
  259.                 OnPropertyChanged();  
  260.                 if (CollectionChanged != null) CollectionChanged(thisnew NotifyCollectionChangedEventArgs(action, newItem, oldItem, index));  
  261.             }  
  262.   
  263.             private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems, int index)  
  264.             {  
  265.                 OnPropertyChanged();  
  266.                 if (CollectionChanged != null) CollectionChanged(thisnew NotifyCollectionChangedEventArgs(action, newItems, index));  
  267.             }  
  268.   
  269.             public override string ToString()  
  270.             {  
  271.                 return string.Format("ObservableDictionary<{0}> Count={1}", GetKeyAndValue(Dictionary.GetType().GetGenericArguments()), Count);  
  272.             }  
  273.   
  274.             private object GetKeyAndValue(Type[] Types)  
  275.             {  
  276.                 string result = string.Empty;  
  277.   
  278.                 foreach (Type type in Types)  
  279.                 {  
  280.                     result += type.ToString() + ",";  
  281.                 }  
  282.   
  283.                 if (!string.IsNullOrEmpty(result) && result.Length > 1)  
  284.                     result = result.Substring(0, result.Length - 1);  
  285.   
  286.                 return result;  
  287.             }  
  288.         }  
  289. }  
Pruébalo y dime cómo va.

No hay comentarios: