Add ObservableDictionary

This commit is contained in:
Mira 2022-10-14 13:18:36 +02:00
parent f63fdfca2f
commit 6031bb3f00
Signed by untrusted user who does not match committer: Xorog
GPG key ID: 983798ED9C3E7C36
4 changed files with 144 additions and 7 deletions

View file

@ -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

View file

@ -0,0 +1,133 @@
using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace Xorog.UniversalExtensions.Entities;
public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> _items = new();
public event EventHandler<ObservableListUpdate<KeyValuePair<TKey, TValue>>> ItemsChanged = delegate { };
public TValue this[TKey key] { get => _items[key]; set => _items[key] = value; }
public ICollection<TKey> Keys => _items.Keys;
public ICollection<TValue> 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<KeyValuePair<TKey, TValue>>() { new(key, value) },
RemovedItems = null
});
});
}
public void Add(KeyValuePair<TKey, TValue> item)
{
_items.Add(item.Key, item.Value);
_ = Task.Run(() =>
{
this.ItemsChanged.Invoke(null, new()
{
List = this.ToList(),
NewItems = new List<KeyValuePair<TKey, TValue>>() { 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<KeyValuePair<TKey, TValue>>() { new(key, old) },
});
});
return v;
}
public bool Remove(KeyValuePair<TKey, TValue> 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<KeyValuePair<TKey, TValue>>() { new(item.Key, old) },
});
});
return v;
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
List<KeyValuePair<TKey, TValue>> newArrayBuild = new();
for (var i = 0; i < array.Length; i++)
{
if (i == arrayIndex)
newArrayBuild.AddRange(this._items);
KeyValuePair<TKey, TValue> b = array[i];
newArrayBuild.Add(b);
}
array = newArrayBuild.ToArray();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
=> _items.Contains(item);
public bool ContainsKey(TKey key)
=> _items.ContainsKey(key);
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
=> _items.GetEnumerator();
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
=> _items.TryGetValue(key, out value);
IEnumerator IEnumerable.GetEnumerator()
=> _items.GetEnumerator();
}

View file

@ -22,7 +22,7 @@ public class ObservableList<T> : IList<T>
{
this.ItemsChanged.Invoke(null, new ObservableListUpdate<T>
{
List = this,
List = this.ToList(),
NewItems = new List<T>() { item },
RemovedItems = null
});
@ -37,7 +37,7 @@ public class ObservableList<T> : IList<T>
{
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
{
List = this,
List = this.ToList(),
NewItems = new List<T>() { item },
RemovedItems = null
});
@ -46,15 +46,16 @@ public class ObservableList<T> : IList<T>
public void Clear()
{
var oldList = _items.ToList();
_items.Clear();
_ = Task.Run(() =>
{
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
{
List = this,
List = this.ToList(),
NewItems = null,
RemovedItems = _items.ToList()
RemovedItems = oldList
});
});
}
@ -63,7 +64,7 @@ public class ObservableList<T> : IList<T>
{
ObservableListUpdate<T> e = new ObservableListUpdate<T>
{
List = this,
List = this.ToList(),
NewItems = null,
RemovedItems = new List<T>() { _items.ElementAt(index) }
};
@ -84,7 +85,7 @@ public class ObservableList<T> : IList<T>
{
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
{
List = this,
List = this.ToList(),
NewItems = null,
RemovedItems = new List<T>() { item }
});

View file

@ -2,7 +2,7 @@
public class ObservableListUpdate<T>
{
public ObservableList<T>? List { get; internal set; }
public List<T>? List { get; internal set; }
public IReadOnlyList<T>? NewItems { get; internal set; }
public IReadOnlyList<T>? RemovedItems { get; internal set; }