Add ObservableDictionary
This commit is contained in:
parent
f63fdfca2f
commit
6031bb3f00
4 changed files with 144 additions and 7 deletions
|
|
@ -29,3 +29,6 @@ dotnet_diagnostic.DV2001.severity = none
|
||||||
|
|
||||||
# CS8602: Dereference of a possibly null reference.
|
# CS8602: Dereference of a possibly null reference.
|
||||||
dotnet_diagnostic.CS8602.severity = silent
|
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
|
||||||
|
|
|
||||||
133
Entities/ObservableDictionary.cs
Normal file
133
Entities/ObservableDictionary.cs
Normal 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();
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ public class ObservableList<T> : IList<T>
|
||||||
{
|
{
|
||||||
this.ItemsChanged.Invoke(null, new ObservableListUpdate<T>
|
this.ItemsChanged.Invoke(null, new ObservableListUpdate<T>
|
||||||
{
|
{
|
||||||
List = this,
|
List = this.ToList(),
|
||||||
NewItems = new List<T>() { item },
|
NewItems = new List<T>() { item },
|
||||||
RemovedItems = null
|
RemovedItems = null
|
||||||
});
|
});
|
||||||
|
|
@ -37,7 +37,7 @@ public class ObservableList<T> : IList<T>
|
||||||
{
|
{
|
||||||
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
||||||
{
|
{
|
||||||
List = this,
|
List = this.ToList(),
|
||||||
NewItems = new List<T>() { item },
|
NewItems = new List<T>() { item },
|
||||||
RemovedItems = null
|
RemovedItems = null
|
||||||
});
|
});
|
||||||
|
|
@ -46,15 +46,16 @@ public class ObservableList<T> : IList<T>
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
var oldList = _items.ToList();
|
||||||
_items.Clear();
|
_items.Clear();
|
||||||
|
|
||||||
_ = Task.Run(() =>
|
_ = Task.Run(() =>
|
||||||
{
|
{
|
||||||
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
||||||
{
|
{
|
||||||
List = this,
|
List = this.ToList(),
|
||||||
NewItems = null,
|
NewItems = null,
|
||||||
RemovedItems = _items.ToList()
|
RemovedItems = oldList
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +64,7 @@ public class ObservableList<T> : IList<T>
|
||||||
{
|
{
|
||||||
ObservableListUpdate<T> e = new ObservableListUpdate<T>
|
ObservableListUpdate<T> e = new ObservableListUpdate<T>
|
||||||
{
|
{
|
||||||
List = this,
|
List = this.ToList(),
|
||||||
NewItems = null,
|
NewItems = null,
|
||||||
RemovedItems = new List<T>() { _items.ElementAt(index) }
|
RemovedItems = new List<T>() { _items.ElementAt(index) }
|
||||||
};
|
};
|
||||||
|
|
@ -84,7 +85,7 @@ public class ObservableList<T> : IList<T>
|
||||||
{
|
{
|
||||||
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
this.ItemsChanged?.Invoke(null, new ObservableListUpdate<T>
|
||||||
{
|
{
|
||||||
List = this,
|
List = this.ToList(),
|
||||||
NewItems = null,
|
NewItems = null,
|
||||||
RemovedItems = new List<T>() { item }
|
RemovedItems = new List<T>() { item }
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
public class ObservableListUpdate<T>
|
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>? NewItems { get; internal set; }
|
||||||
public IReadOnlyList<T>? RemovedItems { get; internal set; }
|
public IReadOnlyList<T>? RemovedItems { get; internal set; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue