diff --git a/.editorconfig b/.editorconfig index e50f5b5..4929470 100644 --- a/.editorconfig +++ b/.editorconfig @@ -29,3 +29,6 @@ dotnet_diagnostic.DV2001.severity = none # CS8602: Dereference of a possibly null reference. dotnet_diagnostic.CS8602.severity = silent + +# CS8714: The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. +dotnet_diagnostic.CS8714.severity = none diff --git a/Entities/ObservableDictionary.cs b/Entities/ObservableDictionary.cs new file mode 100644 index 0000000..5cf8273 --- /dev/null +++ b/Entities/ObservableDictionary.cs @@ -0,0 +1,133 @@ +using System.Collections; +using System.Diagnostics.CodeAnalysis; + +namespace Xorog.UniversalExtensions.Entities; + +public class ObservableDictionary : IDictionary +{ + private Dictionary _items = new(); + + public event EventHandler>> ItemsChanged = delegate { }; + + public TValue this[TKey key] { get => _items[key]; set => _items[key] = value; } + + public ICollection Keys => _items.Keys; + + public ICollection Values => _items.Values; + + public int Count => _items.Count; + + public bool IsReadOnly => false; + + public void Add(TKey key, TValue value) + { + _items.Add(key, value); + + _ = Task.Run(() => + { + this.ItemsChanged.Invoke(null, new() + { + List = this.ToList(), + NewItems = new List>() { new(key, value) }, + RemovedItems = null + }); + }); + } + + public void Add(KeyValuePair item) + { + _items.Add(item.Key, item.Value); + + _ = Task.Run(() => + { + this.ItemsChanged.Invoke(null, new() + { + List = this.ToList(), + NewItems = new List>() { new(item.Key, item.Value) }, + RemovedItems = null + }); + }); + } + + public void Clear() + { + var oldList = _items.ToList(); + _items.Clear(); + + _ = Task.Run(() => + { + this.ItemsChanged.Invoke(null, new() + { + List = this.ToList(), + NewItems = null, + RemovedItems = oldList + }); + }); + } + + public bool Remove(TKey key) + { + var old = _items[key]; + var v = _items.Remove(key); + + _ = Task.Run(() => + { + this.ItemsChanged.Invoke(null, new() + { + List = this.ToList(), + NewItems = null, + RemovedItems = new List>() { new(key, old) }, + }); + }); + + return v; + } + + public bool Remove(KeyValuePair item) + { + var old = _items[item.Key]; + var v = _items.Remove(item.Key); + + _ = Task.Run(() => + { + this.ItemsChanged.Invoke(null, new() + { + List = this.ToList(), + NewItems = null, + RemovedItems = new List>() { new(item.Key, old) }, + }); + }); + return v; + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + List> newArrayBuild = new(); + + for (var i = 0; i < array.Length; i++) + { + if (i == arrayIndex) + newArrayBuild.AddRange(this._items); + + KeyValuePair b = array[i]; + newArrayBuild.Add(b); + } + + array = newArrayBuild.ToArray(); + } + + public bool Contains(KeyValuePair item) + => _items.Contains(item); + + public bool ContainsKey(TKey key) + => _items.ContainsKey(key); + + public IEnumerator> GetEnumerator() + => _items.GetEnumerator(); + + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) + => _items.TryGetValue(key, out value); + + IEnumerator IEnumerable.GetEnumerator() + => _items.GetEnumerator(); +} diff --git a/Entities/ObservableList.cs b/Entities/ObservableList.cs index 0c07a4f..fa519b8 100644 --- a/Entities/ObservableList.cs +++ b/Entities/ObservableList.cs @@ -22,7 +22,7 @@ public class ObservableList : IList { this.ItemsChanged.Invoke(null, new ObservableListUpdate { - List = this, + List = this.ToList(), NewItems = new List() { item }, RemovedItems = null }); @@ -37,7 +37,7 @@ public class ObservableList : IList { this.ItemsChanged?.Invoke(null, new ObservableListUpdate { - List = this, + List = this.ToList(), NewItems = new List() { item }, RemovedItems = null }); @@ -46,15 +46,16 @@ public class ObservableList : IList public void Clear() { + var oldList = _items.ToList(); _items.Clear(); _ = Task.Run(() => { this.ItemsChanged?.Invoke(null, new ObservableListUpdate { - List = this, + List = this.ToList(), NewItems = null, - RemovedItems = _items.ToList() + RemovedItems = oldList }); }); } @@ -63,7 +64,7 @@ public class ObservableList : IList { ObservableListUpdate e = new ObservableListUpdate { - List = this, + List = this.ToList(), NewItems = null, RemovedItems = new List() { _items.ElementAt(index) } }; @@ -84,7 +85,7 @@ public class ObservableList : IList { this.ItemsChanged?.Invoke(null, new ObservableListUpdate { - List = this, + List = this.ToList(), NewItems = null, RemovedItems = new List() { item } }); diff --git a/Entities/ObservableListUpdate.cs b/Entities/ObservableListUpdate.cs index 27e1f49..79dfee7 100644 --- a/Entities/ObservableListUpdate.cs +++ b/Entities/ObservableListUpdate.cs @@ -2,7 +2,7 @@ public class ObservableListUpdate { - public ObservableList? List { get; internal set; } + public List? List { get; internal set; } public IReadOnlyList? NewItems { get; internal set; } public IReadOnlyList? RemovedItems { get; internal set; }