You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.9 KiB
125 lines
4.9 KiB
using System.Collections; |
|
using System.Collections.Generic; |
|
using System.Collections.Specialized; |
|
using System.ComponentModel; |
|
using System.Diagnostics.CodeAnalysis; |
|
|
|
namespace StabilityMatrix.Avalonia.Models; |
|
|
|
public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, |
|
INotifyCollectionChanged, INotifyPropertyChanged where TKey : notnull |
|
{ |
|
private readonly IDictionary<TKey, TValue> dictionary; |
|
|
|
public event NotifyCollectionChangedEventHandler? CollectionChanged; |
|
public event PropertyChangedEventHandler? PropertyChanged; |
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => dictionary.GetEnumerator(); |
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
|
|
|
public ObservableDictionary() |
|
{ |
|
dictionary = new Dictionary<TKey, TValue>(); |
|
} |
|
|
|
public ObservableDictionary(Dictionary<TKey, TValue> dictionary) |
|
{ |
|
this.dictionary = dictionary; |
|
} |
|
|
|
public void Add(KeyValuePair<TKey, TValue> item) |
|
{ |
|
dictionary.Add(item); |
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
} |
|
|
|
public void Clear() |
|
{ |
|
dictionary.Clear(); |
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
} |
|
|
|
public bool Contains(KeyValuePair<TKey, TValue> item) => dictionary.Contains(item); |
|
|
|
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) |
|
{ |
|
dictionary.CopyTo(array, arrayIndex); |
|
} |
|
|
|
public bool Remove(KeyValuePair<TKey, TValue> item) |
|
{ |
|
var success = dictionary.Remove(item); |
|
if (!success) return false; |
|
|
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
|
|
return success; |
|
} |
|
|
|
public int Count => dictionary.Count; |
|
public bool IsReadOnly => dictionary.IsReadOnly; |
|
|
|
public void Add(TKey key, TValue value) |
|
{ |
|
dictionary.Add(key, value); |
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, |
|
new KeyValuePair<TKey, TValue>(key, value))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
} |
|
|
|
public bool ContainsKey(TKey key) => dictionary.ContainsKey(key); |
|
|
|
public bool Remove(TKey key) |
|
{ |
|
var success = dictionary.TryGetValue(key, out var value) && dictionary.Remove(key); |
|
if (!success) return false; |
|
|
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, |
|
new KeyValuePair<TKey, TValue>(key, value!))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
|
|
return success; |
|
} |
|
|
|
public bool TryGetValue([NotNull] TKey key, [MaybeNullWhen(false)] out TValue value) |
|
=> dictionary.TryGetValue(key, out value); |
|
|
|
public TValue this[TKey key] |
|
{ |
|
get => dictionary[key]; |
|
set |
|
{ |
|
var exists = dictionary.ContainsKey(key); |
|
var action = exists |
|
? NotifyCollectionChangedAction.Replace |
|
: NotifyCollectionChangedAction.Add; |
|
dictionary[key] = value; |
|
CollectionChanged?.Invoke(this, |
|
new NotifyCollectionChangedEventArgs(action, dictionary[key])); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Keys))); |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Values))); |
|
} |
|
} |
|
|
|
public ICollection<TKey> Keys => dictionary.Keys; |
|
public ICollection<TValue> Values => dictionary.Values; |
|
}
|
|
|