c#的ObservableDictionary

我正在尝试使用ObservableDictionary的以下实现: ObservableDictionary(C#) 。

当我将字典绑定到DataGrid时使用以下代码:

ObserveableDictionary dd=new ObserveableDictionary(); .... dd["aa"]="bb"; .... dd["aa"]="cc"; 

at dd["aa"]="cc"; 我得到了以下exception

 Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index 

在以下方法中, CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem)中抛出此exception:

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

index参数似乎对应于KeyValuePair oldItem

KeyValuePair如何超出范围,我该怎么做才能使其工作?

类似的数据结构,绑定到Dictionary类型集合

http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/

它提供了一个新的数据结构ObservableDictionary,并在基础Dictionary的任何更改的情况下触发PropertyChanged 。

这是我最后做的事情:

 [Serializable] public class ObservableKeyValuePair:INotifyPropertyChanged { #region properties private TKey key; private TValue value; public TKey Key { get { return key; } set { key = value; OnPropertyChanged("Key"); } } public TValue Value { get { return value; } set { this.value = value; OnPropertyChanged("Value"); } } #endregion #region INotifyPropertyChanged Members [field:NonSerialized] public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(name)); } #endregion } [Serializable] public class ObservableDictionary:ObservableCollection>, IDictionary { #region IDictionary Members public void Add(TKey key, TValue value) { if (ContainsKey(key)) { throw new ArgumentException("The dictionary already contains the key"); } base.Add(new ObservableKeyValuePair() {Key = key, Value = value}); } public bool ContainsKey(TKey key) { //var m=base.FirstOrDefault((i) => i.Key == key); var r = ThisAsCollection().FirstOrDefault((i) => Equals(key, i.Key)); return !Equals(default(ObservableKeyValuePair), r); } bool Equals(TKey a, TKey b) { return EqualityComparer.Default.Equals(a, b); } private ObservableCollection> ThisAsCollection() { return this; } public ICollection Keys { get { return (from i in ThisAsCollection() select i.Key).ToList(); } } public bool Remove(TKey key) { var remove = ThisAsCollection().Where(pair => Equals(key, pair.Key)).ToList(); foreach (var pair in remove) { ThisAsCollection().Remove(pair); } return remove.Count > 0; } public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); var r = GetKvpByTheKey(key); if (!Equals(r, default(ObservableKeyValuePair))) { return false; } value = r.Value; return true; } private ObservableKeyValuePair GetKvpByTheKey(TKey key) { return ThisAsCollection().FirstOrDefault((i) => i.Key.Equals(key)); } public ICollection Values { get { return (from i in ThisAsCollection() select i.Value).ToList(); } } public TValue this[TKey key] { get { TValue result; if (!TryGetValue(key,out result)) { throw new ArgumentException("Key not found"); } return result; } set { if (ContainsKey(key)) { GetKvpByTheKey(key).Value = value; } else { Add(key, value); } } } #endregion #region ICollection> Members public void Add(KeyValuePair item) { Add(item.Key, item.Value); } public bool Contains(KeyValuePair item) { var r = GetKvpByTheKey(item.Key); if (Equals(r, default(ObservableKeyValuePair))) { return false; } return Equals(r.Value, item.Value); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { throw new NotImplementedException(); } public bool IsReadOnly { get { return false; } } public bool Remove(KeyValuePair item) { var r = GetKvpByTheKey(item.Key); if (Equals(r, default(ObservableKeyValuePair))) { return false; } if (!Equals(r.Value,item.Value)) { return false ; } return ThisAsCollection().Remove(r); } #endregion #region IEnumerable> Members public new IEnumerator> GetEnumerator() { return (from i in ThisAsCollection() select new KeyValuePair(i.Key, i.Value)).ToList().GetEnumerator(); } #endregion } 

这个实现看起来像用户的字典,就像ObservableCollection到WPF一样

即使我使用的是github的ObservableDictionary,我也遇到了这个例外。 我之后在类级别声明了字典变量,我尝试在访问它的方法中创建一个新实例。

给出exception的OldCode:

 public class CName { ObservableDictionary _classVariableDictionary = new ObservableDictionary(); } 

NewCode工作:

 public void MethodName() { ObservableDictionary _localVariableDictionary = new ObservableDictionary(); }