ObservableDictionary wirft bei Aktualisieren eines Wertes Exceptions

  • C#

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    ObservableDictionary wirft bei Aktualisieren eines Wertes Exceptions

    Ich hab von hier eine ObservableDictionary-Klasse, die auch wunderbar funktioniert, bis ich versuche, den Wert eines Eintrags zu aktualisieren. Dann kriege ich diese Exception, die ganz unten im Code der Klasse geworfen wird: d.pr/i/umTb
    Wie kann ich das vermeiden?
    Das ist kein ranziger Fremdhoster, sondern Droplr. :p
    Jdfs. hier der Code vom ObservableDictionary:

    C#-Quellcode

    1. using System;
    2. using System.Linq;
    3. using System.ComponentModel;
    4. using System.Collections.Generic;
    5. using System.Collections.Specialized;
    6. namespace System.Collections.ObjectModel
    7. {
    8. public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
    9. {
    10. private const string CountString = "Count";
    11. private const string IndexerName = "Item[]";
    12. private const string KeysName = "Keys";
    13. private const string ValuesName = "Values";
    14. private IDictionary<TKey, TValue> _Dictionary;
    15. protected IDictionary<TKey, TValue> Dictionary
    16. {
    17. get { return _Dictionary; }
    18. }
    19. #region Constructors
    20. public ObservableDictionary()
    21. {
    22. _Dictionary = new Dictionary<TKey, TValue>();
    23. }
    24. public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
    25. {
    26. _Dictionary = new Dictionary<TKey, TValue>(dictionary);
    27. }
    28. public ObservableDictionary(IEqualityComparer<TKey> comparer)
    29. {
    30. _Dictionary = new Dictionary<TKey, TValue>(comparer);
    31. }
    32. public ObservableDictionary(int capacity)
    33. {
    34. _Dictionary = new Dictionary<TKey, TValue>(capacity);
    35. }
    36. public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
    37. {
    38. _Dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
    39. }
    40. public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
    41. {
    42. _Dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
    43. }
    44. #endregion
    45. #region IDictionary<TKey,TValue> Members
    46. public void Add(TKey key, TValue value)
    47. {
    48. Insert(key, value, true);
    49. }
    50. public bool ContainsKey(TKey key)
    51. {
    52. return Dictionary.ContainsKey(key);
    53. }
    54. public ICollection<TKey> Keys
    55. {
    56. get { return Dictionary.Keys; }
    57. }
    58. public bool Remove(TKey key)
    59. {
    60. if (key == null) throw new ArgumentNullException("key");
    61. TValue value;
    62. Dictionary.TryGetValue(key, out value);
    63. var removed = Dictionary.Remove(key);
    64. if (removed)
    65. //OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value));
    66. OnCollectionChanged();
    67. return removed;
    68. }
    69. public bool TryGetValue(TKey key, out TValue value)
    70. {
    71. return Dictionary.TryGetValue(key, out value);
    72. }
    73. public ICollection<TValue> Values
    74. {
    75. get { return Dictionary.Values; }
    76. }
    77. public TValue this[TKey key]
    78. {
    79. get
    80. {
    81. return Dictionary[key];
    82. }
    83. set
    84. {
    85. Insert(key, value, false);
    86. }
    87. }
    88. #endregion
    89. #region ICollection<KeyValuePair<TKey,TValue>> Members
    90. public void Add(KeyValuePair<TKey, TValue> item)
    91. {
    92. Insert(item.Key, item.Value, true);
    93. }
    94. public void Clear()
    95. {
    96. if (Dictionary.Count > 0)
    97. {
    98. Dictionary.Clear();
    99. OnCollectionChanged();
    100. }
    101. }
    102. public bool Contains(KeyValuePair<TKey, TValue> item)
    103. {
    104. return Dictionary.Contains(item);
    105. }
    106. public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    107. {
    108. Dictionary.CopyTo(array, arrayIndex);
    109. }
    110. public int Count
    111. {
    112. get { return Dictionary.Count; }
    113. }
    114. public bool IsReadOnly
    115. {
    116. get { return Dictionary.IsReadOnly; }
    117. }
    118. public bool Remove(KeyValuePair<TKey, TValue> item)
    119. {
    120. return Remove(item.Key);
    121. }
    122. #endregion
    123. #region IEnumerable<KeyValuePair<TKey,TValue>> Members
    124. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    125. {
    126. return Dictionary.GetEnumerator();
    127. }
    128. #endregion
    129. #region IEnumerable Members
    130. IEnumerator IEnumerable.GetEnumerator()
    131. {
    132. return ((IEnumerable)Dictionary).GetEnumerator();
    133. }
    134. #endregion
    135. #region INotifyCollectionChanged Members
    136. public event NotifyCollectionChangedEventHandler CollectionChanged;
    137. #endregion
    138. #region INotifyPropertyChanged Members
    139. public event PropertyChangedEventHandler PropertyChanged;
    140. #endregion
    141. public void AddRange(IDictionary<TKey, TValue> items)
    142. {
    143. if (items == null) throw new ArgumentNullException("items");
    144. if (items.Count > 0)
    145. {
    146. if (Dictionary.Count > 0)
    147. {
    148. if (items.Keys.Any((k) => Dictionary.ContainsKey(k)))
    149. throw new ArgumentException("An item with the same key has already been added.");
    150. else
    151. foreach (var item in items) Dictionary.Add(item);
    152. }
    153. else
    154. _Dictionary = new Dictionary<TKey, TValue>(items);
    155. OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray());
    156. }
    157. }
    158. private void Insert(TKey key, TValue value, bool add)
    159. {
    160. if (key == null) throw new ArgumentNullException("key");
    161. TValue item;
    162. if (Dictionary.TryGetValue(key, out item))
    163. {
    164. if (add) throw new ArgumentException("An item with the same key has already been added.");
    165. if (Equals(item, value)) return;
    166. Dictionary[key] = value;
    167. OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item));
    168. }
    169. else
    170. {
    171. Dictionary[key] = value;
    172. OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value));
    173. }
    174. }
    175. private void OnPropertyChanged()
    176. {
    177. OnPropertyChanged(CountString);
    178. OnPropertyChanged(IndexerName);
    179. OnPropertyChanged(KeysName);
    180. OnPropertyChanged(ValuesName);
    181. }
    182. protected virtual void OnPropertyChanged(string propertyName)
    183. {
    184. if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    185. }
    186. private void OnCollectionChanged()
    187. {
    188. OnPropertyChanged();
    189. if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    190. }
    191. private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem)
    192. {
    193. OnPropertyChanged();
    194. if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem));
    195. }
    196. private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
    197. {
    198. OnPropertyChanged();
    199. if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem));
    200. }
    201. private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems)
    202. {
    203. OnPropertyChanged();
    204. if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItems));
    205. }
    206. }
    207. }


    Hier mein Code, der die Exception auslöst:

    C#-Quellcode

    1. private void WH_EditColor_Click(object sender, RoutedEventArgs e) {
    2. KeyValuePair<string, Color?> source;
    3. source = (KeyValuePair<string, Color?>)(((ListBoxItem)((Grid)((Button)e.Source).Parent).TemplatedParent).Content);
    4. ColorPicker cp = new ColorPicker(); //Ein selbstgemachter Colorpicker, dessen ChosenColor-Eigenschaft die gewählte Farbe enthält
    5. cp.colorCanvas1.HexadecimalString = source.Value.Value.ToString();
    6. if(cp.ShowDialog() == true) {
    7. App.Wallpapers[source.Key] = cp.ChosenColor;
    8. //hier wird die Exception ausgelöst, wenn die cp.ChosenColor nen anderen Wert hat als der Wert des KeyValuePairs im Dictionary
    9. }
    10. }


    Hier die Exception:
    klingt so, als gebe es den Key nicht im Dictionary


    das ist aber auch unklar:
    hier wird die Exception ausgelöst, wenn die cp.ChosenColor nen anderen Wert hat als der Wert des KeyValuePairs im Dictionary
    Eine ChosenColor ist ja kein KeyValuePair - hat also immer "nen anderen Wert hat als der Wert des KeyValuePairs im Dictionary"
    Den Key gibt es aber. Ich den passenden Wert ja ausgeben lassen und damit arbeiten, nur neu zuweisen kann ich ihn nicht.
    Mit einem normalen Dictionary funktioniert es, aber das kann ich nicht vernünftig an ne Listbox binden.

    Edit:
    hat also immer "nen anderen Wert hat als der Wert des KeyValuePairs im Dictionary"
    Nein. :p
    App.Wallpapers[source.Key] liefert mir den Wert, also ne Color. Wenn diese Color den gleichen Wert hat wie App.Wallpapers[source.Key], passiert nichts.
    Btw: "Wallpapers" ist so deklariert:

    C#-Quellcode

    1. public static ObservableDictionary<String, Color?> Wallpapers { get; set; }
    .

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    2. Dim Hullu As New Dictionary(Of String, String) From {{"Hallo", "HerrBert"}, {"Hielo", "HurBert"}, {"Hällö", "H. Bert"}}
    3. ListBox1.DataSource = Hullu.ToList
    4. ListBox1.DisplayMember = "Value"
    5. End Sub
    Dazu müsste ich die komplette Programmstruktur auf den Kopf stellen, und das würde ich lieber vermeiden. :/
    Edit: Ich hab die Click-Dinger beseitigt und durch Commands ersetzt, was im Endeffekt nichts geändert hat. Der Fehler bei Setzen des Wertes tritt immer noch auf.
    Ich vermute, dass am Dictionary irgendwas nicht stimmt, aber was?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Samus Aran“ ()