ObservableDictionary.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System.Collections.Specialized;
  2. using System.ComponentModel;
  3. using System.Linq;
  4. namespace HistoryView.DataType;
  5. public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged where TKey : notnull
  6. {
  7. public ObservableDictionary() : base()
  8. { }
  9. private int _index;
  10. public event NotifyCollectionChangedEventHandler? CollectionChanged;
  11. public event PropertyChangedEventHandler? PropertyChanged;
  12. public new KeyCollection Keys => base.Keys;
  13. public new ValueCollection Values => base.Values;
  14. public new int Count => base.Count;
  15. public new TValue this[TKey key]
  16. {
  17. get
  18. {
  19. lock (this)
  20. return GetValue(key);
  21. }
  22. set
  23. {
  24. lock (this)
  25. SetValue(key, value);
  26. }
  27. }
  28. //public TValue this[int index]
  29. //{
  30. // get
  31. // {
  32. // lock (this)
  33. // return GetIndexValue(index);
  34. // }
  35. // set
  36. // {
  37. // lock (this)
  38. // SetIndexValue(index, value);
  39. // }
  40. //}
  41. public new bool TryGetValue(TKey key, out TValue? value)
  42. {
  43. lock (this)
  44. return base.TryGetValue(key, out value);
  45. }
  46. public new void Add(TKey key, TValue value)
  47. {
  48. lock (this)
  49. base.Add(key, value);
  50. OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, FindPair(key), _index));
  51. OnPropertyChanged(nameof(Keys));
  52. OnPropertyChanged(nameof(Values));
  53. OnPropertyChanged(nameof(Count));
  54. }
  55. public new void Clear()
  56. {
  57. lock (this)
  58. base.Clear();
  59. OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
  60. OnPropertyChanged(nameof(Keys));
  61. OnPropertyChanged(nameof(Values));
  62. OnPropertyChanged(nameof(Count));
  63. }
  64. public new bool Remove(TKey key)
  65. {
  66. var pair = FindPair(key);
  67. lock (this)
  68. if (base.Remove(key))
  69. {
  70. OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, pair, _index));
  71. OnPropertyChanged(nameof(Keys));
  72. OnPropertyChanged(nameof(Values));
  73. OnPropertyChanged(nameof(Count));
  74. return true;
  75. }
  76. return false;
  77. }
  78. protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
  79. {
  80. CollectionChanged?.Invoke(this, e);
  81. }
  82. protected void OnPropertyChanged(string propertyName)
  83. {
  84. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  85. }
  86. #region private方法
  87. private TValue GetIndexValue(int index)
  88. {
  89. for (int i = 0; i < Count; i++)
  90. {
  91. if (i == index)
  92. {
  93. var pair = this.ElementAt(i);
  94. return pair.Value;
  95. }
  96. }
  97. return default!;
  98. }
  99. private void SetIndexValue(int index, TValue value)
  100. {
  101. try
  102. {
  103. var pair = this.ElementAtOrDefault(index);
  104. SetValue(pair.Key, value);
  105. }
  106. catch (Exception)
  107. {
  108. }
  109. }
  110. private TValue GetValue(TKey key)
  111. {
  112. return ContainsKey(key) ? base[key] : default!;
  113. }
  114. private void SetValue(TKey key, TValue value)
  115. {
  116. if (ContainsKey(key))
  117. {
  118. var pair = FindPair(key);
  119. int index = _index;
  120. base[key] = value;
  121. var newpair = FindPair(key);
  122. OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newpair, pair, index));
  123. OnPropertyChanged(nameof(Values));
  124. OnPropertyChanged("Item[]");
  125. }
  126. else
  127. {
  128. Add(key, value);
  129. }
  130. }
  131. private KeyValuePair<TKey, TValue> FindPair(TKey key)
  132. {
  133. _index = 0;
  134. foreach (var item in this)
  135. {
  136. if (item.Key!.Equals(key))
  137. return item;
  138. _index++;
  139. }
  140. return default;
  141. }
  142. private int IndexOf(TKey key)
  143. {
  144. int index = 0;
  145. foreach (var item in this)
  146. {
  147. if (item.Key!.Equals(key))
  148. return index;
  149. index++;
  150. }
  151. return -1;
  152. }
  153. #endregion
  154. }