patterncsharpMinor
Custom Implementation of ObservableDictionary
Viewed 0 times
observabledictionarycustomimplementation
Problem
I recently found myself in need of an
And since there is not generic implementation of
Here's the entire implementation:
```
public class ObservableDictionary : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
{
private readonly IList values;
private readonly IDictionary indexMap;
private ObservableDictionary.SimpleMonitor _monitor = new ObservableDictionary.SimpleMonitor();
private const string CountString = "Count";
private const string IndexerName = "Item[]";
private const string KeysString = "Keys";
private const string ValuesString = "Values";
#region Constructor
public ObservableDictionary()
{
this.values = new List();
this.indexMap = new Dictionary();
}
public ObservableDictionary(IDictionary dictionary)
{
this.values = new List();
this.indexMap = new Dictionary();
int idx = 0;
foreach (var kvp in dictionary)
{
this.indexMap.Add(kvp.Key, idx);
this.values.Add(kvp.Value);
idx++;
}
}
public ObservableDictionary(int capacity)
{
this.values = new List(capacity);
this.indexMap = new Dictionary(capacity);
}
#endregion
#region Virtual Add/Remove/Change Control Methods
protected virtual void AddItem(TKey key, TValue value)
{
this.CheckReentrancy();
var index = this.values.Count;
this.indexMap.Add(key, index);
IDictionary implementation that was observable from a WPF UI. Since the .Net framework does not provide one, I rolled my own, but borrowed very heavily from what ObservableCollection does on its own.And since there is not generic implementation of
OrderedDictionary where I can lookup by both index and key, I used 2 internal collections to provide for key lookup and indexed values.// stores an indexed list of values in the collection
private readonly IList values;
// stores the keys and the associated index
private readonly IDictionary indexMap;Here's the entire implementation:
```
public class ObservableDictionary : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
{
private readonly IList values;
private readonly IDictionary indexMap;
private ObservableDictionary.SimpleMonitor _monitor = new ObservableDictionary.SimpleMonitor();
private const string CountString = "Count";
private const string IndexerName = "Item[]";
private const string KeysString = "Keys";
private const string ValuesString = "Values";
#region Constructor
public ObservableDictionary()
{
this.values = new List();
this.indexMap = new Dictionary();
}
public ObservableDictionary(IDictionary dictionary)
{
this.values = new List();
this.indexMap = new Dictionary();
int idx = 0;
foreach (var kvp in dictionary)
{
this.indexMap.Add(kvp.Key, idx);
this.values.Add(kvp.Value);
idx++;
}
}
public ObservableDictionary(int capacity)
{
this.values = new List(capacity);
this.indexMap = new Dictionary(capacity);
}
#endregion
#region Virtual Add/Remove/Change Control Methods
protected virtual void AddItem(TKey key, TValue value)
{
this.CheckReentrancy();
var index = this.values.Count;
this.indexMap.Add(key, index);
Solution
There is a bug in the "Values" property. It should return this.values (lower case "v") not this.Values (upper case "V"). Also the collection returned may not represent the way ordered in the way indexMap would have returned. See remarks section at https://msdn.microsoft.com/en-us/library/0yxt5h4s(v=vs.110).aspx.
Context
StackExchange Code Review Q#116562, answer score: 3
Revisions (0)
No revisions yet.