using System.Collections.Specialized; using System.ComponentModel; using System.Linq; namespace HistoryView.DataType; public class ObservableDictionary : Dictionary, INotifyCollectionChanged, INotifyPropertyChanged where TKey : notnull { public ObservableDictionary() : base() { } private int _index; public event NotifyCollectionChangedEventHandler? CollectionChanged; public event PropertyChangedEventHandler? PropertyChanged; public new KeyCollection Keys => base.Keys; public new ValueCollection Values => base.Values; public new int Count => base.Count; public new TValue this[TKey key] { get { lock (this) return GetValue(key); } set { lock (this) SetValue(key, value); } } //public TValue this[int index] //{ // get // { // lock (this) // return GetIndexValue(index); // } // set // { // lock (this) // SetIndexValue(index, value); // } //} public new bool TryGetValue(TKey key, out TValue? value) { lock (this) return base.TryGetValue(key, out value); } public new void Add(TKey key, TValue value) { lock (this) base.Add(key, value); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, FindPair(key), _index)); OnPropertyChanged(nameof(Keys)); OnPropertyChanged(nameof(Values)); OnPropertyChanged(nameof(Count)); } public new void Clear() { lock (this) base.Clear(); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); OnPropertyChanged(nameof(Keys)); OnPropertyChanged(nameof(Values)); OnPropertyChanged(nameof(Count)); } public new bool Remove(TKey key) { var pair = FindPair(key); lock (this) if (base.Remove(key)) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, pair, _index)); OnPropertyChanged(nameof(Keys)); OnPropertyChanged(nameof(Values)); OnPropertyChanged(nameof(Count)); return true; } return false; } protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { CollectionChanged?.Invoke(this, e); } protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #region private方法 private TValue GetIndexValue(int index) { for (int i = 0; i < Count; i++) { if (i == index) { var pair = this.ElementAt(i); return pair.Value; } } return default!; } private void SetIndexValue(int index, TValue value) { try { var pair = this.ElementAtOrDefault(index); SetValue(pair.Key, value); } catch (Exception) { } } private TValue GetValue(TKey key) { return ContainsKey(key) ? base[key] : default!; } private void SetValue(TKey key, TValue value) { if (ContainsKey(key)) { var pair = FindPair(key); int index = _index; base[key] = value; var newpair = FindPair(key); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newpair, pair, index)); OnPropertyChanged(nameof(Values)); OnPropertyChanged("Item[]"); } else { Add(key, value); } } private KeyValuePair FindPair(TKey key) { _index = 0; foreach (var item in this) { if (item.Key!.Equals(key)) return item; _index++; } return default; } private int IndexOf(TKey key) { int index = 0; foreach (var item in this) { if (item.Key!.Equals(key)) return index; index++; } return -1; } #endregion }