|
|
|
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;
|
|
|
|
}
|