Merge pull request #30 from Cysharp/hadashiA/remove-change-kind
Add a dedicated event type for SynchronizedView
This commit is contained in:
commit
f5bf911c82
24
README.md
24
README.md
@ -278,15 +278,15 @@ public class SampleScript : MonoBehaviour
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void OnCollectionChanged(ChangedKind changedKind, int value, GameObject view, in NotifyCollectionChangedEventArgs<int> eventArgs)
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<int, GameObject> eventArgs)
|
||||
{
|
||||
if (changedKind == ChangedKind.Add)
|
||||
if (eventArgs.Action == NotifyCollectionChangedAction.Add)
|
||||
{
|
||||
view.transform.SetParent(root.transform);
|
||||
eventArgs.NewView.transform.SetParent(root.transform);
|
||||
}
|
||||
else if (changedKind == ChangedKind.Remove)
|
||||
else if (NotifyCollectionChangedAction.Remove)
|
||||
{
|
||||
GameObject.Destroy(view);
|
||||
GameObject.Destroy(eventArgs.OldView);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +336,7 @@ public interface ISynchronizedView<T, TView> : IReadOnlyCollection<(T Value, TVi
|
||||
|
||||
void AttachFilter(ISynchronizedViewFilter<T, TView> filter);
|
||||
void ResetFilter(Action<T, TView>? resetAction);
|
||||
INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged();
|
||||
INotifyCollectionChangedSynchronizedView<T, TView> ToNotifyCollectionChanged();
|
||||
}
|
||||
```
|
||||
|
||||
@ -385,12 +385,18 @@ public interface ISynchronizedViewFilter<T, TView>
|
||||
bool IsMatch(T value, TView view);
|
||||
void WhenTrue(T value, TView view);
|
||||
void WhenFalse(T value, TView view);
|
||||
void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs);
|
||||
void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> eventArgs);
|
||||
}
|
||||
|
||||
public enum ChangedKind
|
||||
public readonly struct SynchronizedViewChangedEventArgs<T, TView>
|
||||
{
|
||||
Add, Remove, Move
|
||||
public readonly NotifyCollectionChangedAction Action = action;
|
||||
public readonly T NewValue = newValue;
|
||||
public readonly T OldValue = oldValue;
|
||||
public readonly TView NewView = newView;
|
||||
public readonly TView OldView = oldView;
|
||||
public readonly int NewViewIndex = newViewIndex;
|
||||
public readonly int OldViewIndex = oldViewIndex;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using R3;
|
||||
using System.Linq;
|
||||
using ObservableCollections;
|
||||
@ -64,25 +65,26 @@ class HogeFilter : ISynchronizedViewFilter<int, ViewModel>
|
||||
view.Value = $"@{value} (odd)";
|
||||
}
|
||||
|
||||
public void OnCollectionChanged(
|
||||
ChangedKind changedKind,
|
||||
int value,
|
||||
ViewModel view,
|
||||
in NotifyCollectionChangedEventArgs<int> eventArgs)
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<int, ViewModel> eventArgs)
|
||||
{
|
||||
switch (changedKind)
|
||||
switch (eventArgs.Action)
|
||||
{
|
||||
case ChangedKind.Add:
|
||||
view.Value += " Add";
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
eventArgs.NewView.Value += " Add";
|
||||
break;
|
||||
case ChangedKind.Remove:
|
||||
view.Value += " Remove";
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
eventArgs.OldView.Value += " Remove";
|
||||
break;
|
||||
case ChangedKind.Move:
|
||||
view.Value += $" Move {eventArgs.OldStartingIndex} {eventArgs.NewStartingIndex}";
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
eventArgs.NewView.Value += $" Move {eventArgs.OldViewIndex} {eventArgs.NewViewIndex}";
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
eventArgs.NewView.Value += $" Replace {eventArgs.NewViewIndex}";
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(changedKind), changedKind, null);
|
||||
throw new ArgumentOutOfRangeException(nameof(eventArgs.Action), eventArgs.Action, null);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace ObservableCollections
|
||||
{
|
||||
public readonly struct SynchronizedViewChangedEventArgs<T, TView>(
|
||||
NotifyCollectionChangedAction action,
|
||||
T newValue = default!,
|
||||
T oldValue = default!,
|
||||
TView newView = default!,
|
||||
TView oldView = default!,
|
||||
int newViewIndex = -1,
|
||||
int oldViewIndex = -1)
|
||||
{
|
||||
public readonly NotifyCollectionChangedAction Action = action;
|
||||
public readonly T NewValue = newValue;
|
||||
public readonly T OldValue = oldValue;
|
||||
public readonly TView NewView = newView;
|
||||
public readonly TView OldView = oldView;
|
||||
public readonly int NewViewIndex = newViewIndex;
|
||||
public readonly int OldViewIndex = oldViewIndex;
|
||||
}
|
||||
|
||||
public interface ISynchronizedViewFilter<T, TView>
|
||||
{
|
||||
bool IsMatch(T value, TView view);
|
||||
void WhenTrue(T value, TView view);
|
||||
void WhenFalse(T value, TView view);
|
||||
void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs);
|
||||
void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> eventArgs);
|
||||
}
|
||||
|
||||
public enum ChangedKind
|
||||
{
|
||||
Add, Remove, Move
|
||||
}
|
||||
|
||||
public class SynchronizedViewFilter<T, TView> : ISynchronizedViewFilter<T, TView>
|
||||
public class SynchronizedViewFilter<T, TView>(
|
||||
Func<T, TView, bool> isMatch,
|
||||
Action<T, TView>? whenTrue,
|
||||
Action<T, TView>? whenFalse,
|
||||
Action<SynchronizedViewChangedEventArgs<T, TView>>? onCollectionChanged)
|
||||
: ISynchronizedViewFilter<T, TView>
|
||||
{
|
||||
public static readonly ISynchronizedViewFilter<T, TView> Null = new NullViewFilter();
|
||||
|
||||
readonly Func<T, TView, bool> isMatch;
|
||||
readonly Action<T, TView>? whenTrue;
|
||||
readonly Action<T, TView>? whenFalse;
|
||||
readonly Action<ChangedKind, T, TView>? onCollectionChanged;
|
||||
|
||||
public SynchronizedViewFilter(Func<T, TView, bool> isMatch, Action<T, TView>? whenTrue, Action<T, TView>? whenFalse, Action<ChangedKind, T, TView>? onCollectionChanged)
|
||||
{
|
||||
this.isMatch = isMatch;
|
||||
this.whenTrue = whenTrue;
|
||||
this.whenFalse = whenFalse;
|
||||
this.onCollectionChanged = onCollectionChanged;
|
||||
}
|
||||
|
||||
public bool IsMatch(T value, TView view) => isMatch(value, view);
|
||||
public void WhenFalse(T value, TView view) => whenFalse?.Invoke(value, view);
|
||||
public void WhenTrue(T value, TView view) => whenTrue?.Invoke(value, view);
|
||||
public void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs) => onCollectionChanged?.Invoke(changedKind, value, view);
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> eventArgs) => onCollectionChanged?.Invoke(eventArgs);
|
||||
|
||||
class NullViewFilter : ISynchronizedViewFilter<T, TView>
|
||||
{
|
||||
public bool IsMatch(T value, TView view) => true;
|
||||
public void WhenFalse(T value, TView view) { }
|
||||
public void WhenTrue(T value, TView view) { }
|
||||
public void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs) { }
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> eventArgs) { }
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +64,7 @@ namespace ObservableCollections
|
||||
source.AttachFilter(new SynchronizedViewFilter<T, TView>(isMatch, whenTrue, whenFalse, null));
|
||||
}
|
||||
|
||||
public static void AttachFilter<T, TView>(this ISynchronizedView<T, TView> source, Func<T, TView, bool> isMatch, Action<T, TView>? whenTrue, Action<T, TView>? whenFalse, Action<ChangedKind, T, TView>? onCollectionChanged)
|
||||
public static void AttachFilter<T, TView>(this ISynchronizedView<T, TView> source, Func<T, TView, bool> isMatch, Action<T, TView>? whenTrue, Action<T, TView>? whenFalse, Action<SynchronizedViewChangedEventArgs<T, TView>>? onCollectionChanged)
|
||||
{
|
||||
source.AttachFilter(new SynchronizedViewFilter<T, TView>(isMatch, whenTrue, whenFalse, onCollectionChanged));
|
||||
}
|
||||
@ -68,12 +74,13 @@ namespace ObservableCollections
|
||||
return filter == SynchronizedViewFilter<T, TView>.Null;
|
||||
}
|
||||
|
||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
|
||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, int index)
|
||||
{
|
||||
InvokeOnAdd(filter, value.value, value.view, eventArgs);
|
||||
filter.InvokeOnAdd(value.value, value.view, index);
|
||||
}
|
||||
|
||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, int index)
|
||||
{
|
||||
if (filter.IsMatch(value, view))
|
||||
{
|
||||
@ -83,27 +90,42 @@ namespace ObservableCollections
|
||||
{
|
||||
filter.WhenFalse(value, view);
|
||||
}
|
||||
filter.OnCollectionChanged(ChangedKind.Add, value, view, eventArgs);
|
||||
filter.OnCollectionChanged(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, newValue: value, newView: view, newViewIndex: index));
|
||||
}
|
||||
|
||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, int oldIndex)
|
||||
{
|
||||
InvokeOnRemove(filter, value.value, value.view, eventArgs);
|
||||
filter.InvokeOnRemove(value.value, value.view, oldIndex);
|
||||
}
|
||||
|
||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, int oldIndex)
|
||||
{
|
||||
filter.OnCollectionChanged(ChangedKind.Remove, value, view, eventArgs);
|
||||
filter.OnCollectionChanged(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex));
|
||||
}
|
||||
|
||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, int index, int oldIndex)
|
||||
{
|
||||
InvokeOnMove(filter, value.value, value.view, eventArgs);
|
||||
InvokeOnMove(filter, value.value, value.view, index, oldIndex);
|
||||
}
|
||||
|
||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, int index, int oldIndex)
|
||||
{
|
||||
filter.OnCollectionChanged(ChangedKind.Move, value, view, eventArgs);
|
||||
filter.OnCollectionChanged(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Move, newValue: value, newView: view, newViewIndex: index, oldViewIndex: oldIndex));
|
||||
}
|
||||
|
||||
internal static void InvokeOnReplace<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, (T value, TView view) oldValue, int index, int oldIndex = -1)
|
||||
{
|
||||
filter.InvokeOnReplace(value.value, value.view, oldValue.value, oldValue.view, index, oldIndex);
|
||||
}
|
||||
|
||||
internal static void InvokeOnReplace<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, T oldValue, TView oldView, int index, int oldIndex = -1)
|
||||
{
|
||||
filter.OnCollectionChanged(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Replace, newValue: value, newView: view, oldValue: oldValue, oldView: oldView, newViewIndex: index, oldViewIndex: oldIndex >= 0 ? oldIndex : index));
|
||||
}
|
||||
|
||||
internal static void InvokeOnReset<T, TView>(this ISynchronizedViewFilter<T, TView> filter)
|
||||
{
|
||||
filter.OnCollectionChanged(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
internal static void InvokeOnAttach<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view)
|
||||
|
@ -53,7 +53,7 @@ namespace ObservableCollections.Internal
|
||||
var (value, view) = list[i];
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, i));
|
||||
filter.InvokeOnAdd(value, view, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -161,7 +161,7 @@ namespace ObservableCollections.Internal
|
||||
var (value, view) = array[i];
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, i));
|
||||
filter.InvokeOnAdd(value, view, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -58,25 +58,30 @@ namespace ObservableCollections.Internal
|
||||
public void WhenTrue(T value, TView view) => currentFilter.WhenTrue(value, view);
|
||||
public void WhenFalse(T value, TView view) => currentFilter.WhenFalse(value, view);
|
||||
|
||||
public void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> args)
|
||||
{
|
||||
currentFilter.OnCollectionChanged(changedKind, value, view, in eventArgs);
|
||||
currentFilter.OnCollectionChanged(args);
|
||||
|
||||
switch (changedKind)
|
||||
switch (args.Action)
|
||||
{
|
||||
case ChangedKind.Add:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, view, eventArgs.NewStartingIndex));
|
||||
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
|
||||
return;
|
||||
case ChangedKind.Remove:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, view, eventArgs.OldStartingIndex));
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, args.NewView, args.NewViewIndex));
|
||||
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
|
||||
break;
|
||||
case ChangedKind.Move:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex));
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, args.OldView, args.OldViewIndex));
|
||||
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, args.NewView, args.OldView, args.NewViewIndex));
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, args.NewView, args.NewViewIndex, args.OldViewIndex));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(changedKind), changedKind, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,11 +60,12 @@ namespace ObservableCollections.Internal
|
||||
lock (SyncRoot)
|
||||
{
|
||||
this.filter = filter;
|
||||
var i = 0;
|
||||
foreach (var (_, (value, view)) in list)
|
||||
{
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, -1));
|
||||
filter.InvokeOnAdd(value, view, i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -134,7 +135,7 @@ namespace ObservableCollections.Internal
|
||||
var id = identitySelector(value);
|
||||
list.Add((value, id), (value, view));
|
||||
var index = list.IndexOfKey((value, id));
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
|
||||
filter.InvokeOnAdd(value, view, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -144,7 +145,7 @@ namespace ObservableCollections.Internal
|
||||
var id = identitySelector(value);
|
||||
list.Add((value, id), (value, view));
|
||||
var index = list.IndexOfKey((value, id));
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
|
||||
filter.InvokeOnAdd(value, view, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,7 +161,7 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var index = list.IndexOfKey(key);
|
||||
list.RemoveAt(index);
|
||||
filter.InvokeOnRemove(v.Value, v.View, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, index));
|
||||
filter.InvokeOnRemove(v.Value, v.View, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -173,7 +174,7 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var index = list.IndexOfKey((value, id));
|
||||
list.RemoveAt(index);
|
||||
filter.InvokeOnRemove(v.Value, v.View, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, index));
|
||||
filter.InvokeOnRemove(v.Value, v.View, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,11 +186,11 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var oldValue = e.OldItem;
|
||||
var oldKey = (oldValue, identitySelector(oldValue));
|
||||
var oldIndex = -1;
|
||||
if (list.TryGetValue(oldKey, out var o))
|
||||
{
|
||||
var oldIndex = list.IndexOfKey(oldKey);
|
||||
oldIndex = list.IndexOfKey(oldKey);
|
||||
list.RemoveAt(oldIndex);
|
||||
filter.InvokeOnRemove(o, NotifyCollectionChangedEventArgs<T>.Remove(oldValue, oldIndex));
|
||||
}
|
||||
|
||||
var value = e.NewItem;
|
||||
@ -198,28 +199,24 @@ namespace ObservableCollections.Internal
|
||||
list.Add((value, id), (value, view));
|
||||
var newIndex = list.IndexOfKey((value, id));
|
||||
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, newIndex));
|
||||
filter.InvokeOnReplace((value, view), o, newIndex, oldIndex: oldIndex);
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
{
|
||||
// Move(index change) does not affect sorted list.
|
||||
var oldValue = e.OldItem;
|
||||
if (list.TryGetValue((oldValue, identitySelector(oldValue)), out var view))
|
||||
var oldKey = (oldValue, identitySelector(oldValue));
|
||||
if (list.TryGetValue(oldKey, out var v))
|
||||
{
|
||||
filter.InvokeOnMove(view, e);
|
||||
var index = list.IndexOfKey(oldKey);
|
||||
filter.InvokeOnMove(v, index, index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
filter.InvokeOnRemove(item.Value, e);
|
||||
}
|
||||
}
|
||||
list.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -65,11 +65,12 @@ namespace ObservableCollections.Internal
|
||||
lock (SyncRoot)
|
||||
{
|
||||
this.filter = filter;
|
||||
var i = 0;
|
||||
foreach (var (_, (value, view)) in list)
|
||||
{
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, -1));
|
||||
filter.InvokeOnAdd(value, view, i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -141,7 +142,7 @@ namespace ObservableCollections.Internal
|
||||
list.Add((view, id), (value, view));
|
||||
viewMap.Add(id, view);
|
||||
var index = list.IndexOfKey((view, id));
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
|
||||
filter.InvokeOnAdd(value, view, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -152,7 +153,7 @@ namespace ObservableCollections.Internal
|
||||
list.Add((view, id), (value, view));
|
||||
viewMap.Add(id, view);
|
||||
var index = list.IndexOfKey((view, id));
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
|
||||
filter.InvokeOnAdd(value, view, index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -170,7 +171,7 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var index = list.IndexOfKey(key);
|
||||
list.RemoveAt(index);
|
||||
filter.InvokeOnRemove(v, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, index));
|
||||
filter.InvokeOnRemove(v, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,7 +187,7 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var index = list.IndexOfKey((view, id));
|
||||
list.RemoveAt(index);
|
||||
filter.InvokeOnRemove(v, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, index));
|
||||
filter.InvokeOnRemove(v, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,14 +199,14 @@ namespace ObservableCollections.Internal
|
||||
{
|
||||
var oldValue = e.OldItem;
|
||||
var oldId = identitySelector(oldValue);
|
||||
var oldIndex = -1;
|
||||
if (viewMap.Remove(oldId, out var oldView))
|
||||
{
|
||||
var oldKey = (oldView, oldId);
|
||||
if (list.TryGetValue(oldKey, out var v))
|
||||
{
|
||||
var oldIndex = list.IndexOfKey(oldKey);
|
||||
oldIndex = list.IndexOfKey(oldKey);
|
||||
list.RemoveAt(oldIndex);
|
||||
filter.InvokeOnRemove(oldValue, oldView, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, oldIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,30 +217,25 @@ namespace ObservableCollections.Internal
|
||||
viewMap.Add(id, view);
|
||||
|
||||
var index = list.IndexOfKey((view, id));
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
|
||||
filter.InvokeOnReplace(value, view, oldValue, oldView!, index, oldIndex);
|
||||
break;
|
||||
}
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
// Move(index change) does not affect soreted dict.
|
||||
{
|
||||
var value = e.OldItem;
|
||||
var key = identitySelector(value);
|
||||
if (viewMap.TryGetValue(key, out var view))
|
||||
var id = identitySelector(value);
|
||||
if (viewMap.TryGetValue(id, out var view))
|
||||
{
|
||||
filter.InvokeOnMove(value, view, e);
|
||||
var index = list.IndexOfKey((view, id));
|
||||
filter.InvokeOnMove(value, view, index, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
filter.InvokeOnRemove(item.Value, e);
|
||||
}
|
||||
}
|
||||
list.Clear();
|
||||
viewMap.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -42,48 +42,6 @@ namespace ObservableCollections
|
||||
OldStartingIndex = oldStartingIndex;
|
||||
}
|
||||
|
||||
public NotifyCollectionChangedEventArgs ToStandardEventArgs()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (IsSingleItem)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, NewItem, NewStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, NewItems.ToArray(), NewStartingIndex);
|
||||
}
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
if (IsSingleItem)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, OldItem, OldStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, OldItems.ToArray(), OldStartingIndex);
|
||||
}
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
if (IsSingleItem)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, NewItem, OldItem, NewStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, NewItems.ToArray(), OldItems.ToArray(), NewStartingIndex);
|
||||
}
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs(Action, OldItem, NewStartingIndex, OldStartingIndex);
|
||||
}
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
return new NotifyCollectionChangedEventArgs(Action);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static NotifyCollectionChangedEventArgs<T> Add(T newItem, int newStartingIndex)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Add, true, newItem: newItem, newStartingIndex: newStartingIndex);
|
||||
@ -104,14 +62,14 @@ namespace ObservableCollections
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Remove, false, oldItems: oldItems, oldStartingIndex: oldStartingIndex);
|
||||
}
|
||||
|
||||
public static NotifyCollectionChangedEventArgs<T> Replace(T newItem, T oldItem, int startingIndex)
|
||||
public static NotifyCollectionChangedEventArgs<T> Replace(T newItem, T oldItem, int newStartingIndex, int oldStartingIndex)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Replace, true, newItem: newItem, oldItem: oldItem, newStartingIndex: startingIndex, oldStartingIndex: startingIndex);
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Replace, true, newItem: newItem, oldItem: oldItem, newStartingIndex: newStartingIndex, oldStartingIndex: oldStartingIndex);
|
||||
}
|
||||
|
||||
public static NotifyCollectionChangedEventArgs<T> Replace(ReadOnlySpan<T> newItems, ReadOnlySpan<T> oldItems, int startingIndex)
|
||||
public static NotifyCollectionChangedEventArgs<T> Replace(ReadOnlySpan<T> newItems, ReadOnlySpan<T> oldItems, int newStartingIndex, int oldStartingIndex)
|
||||
{
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Replace, false, newItems: newItems, oldItems: oldItems, newStartingIndex: startingIndex, oldStartingIndex: startingIndex);
|
||||
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Replace, false, newItems: newItems, oldItems: oldItems, newStartingIndex: newStartingIndex, oldStartingIndex: oldStartingIndex);
|
||||
}
|
||||
|
||||
public static NotifyCollectionChangedEventArgs<T> Move(T changedItem, int newStartingIndex, int oldStartingIndex)
|
||||
|
@ -71,7 +71,7 @@ namespace ObservableCollections
|
||||
var view = v.Value.Item2;
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<KeyValuePair<TKey, TValue>>.Add(value, -1));
|
||||
filter.InvokeOnAdd(value, view, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -135,40 +135,30 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = selector(e.NewItem);
|
||||
dict.Add(e.NewItem.Key, (e.NewItem.Value, v));
|
||||
filter.InvokeOnAdd(new KeyValuePair<TKey, TValue>(e.NewItem.Key, e.NewItem.Value), v, e);
|
||||
filter.InvokeOnAdd(e.NewItem, v, -1);
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
{
|
||||
if (dict.Remove(e.OldItem.Key, out var v))
|
||||
{
|
||||
filter.InvokeOnRemove((new KeyValuePair<TKey, TValue>(e.OldItem.Key, v.Item1), v.Item2), e);
|
||||
filter.InvokeOnRemove(e.OldItem, v.Item2, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
{
|
||||
if (dict.Remove(e.OldItem.Key, out var oldView))
|
||||
{
|
||||
filter.InvokeOnRemove((new KeyValuePair<TKey, TValue>(e.OldItem.Key, oldView.Item1), oldView.Item2), e);
|
||||
}
|
||||
|
||||
var v = selector(e.NewItem);
|
||||
dict.Remove(e.OldItem.Key, out var ov);
|
||||
dict[e.NewItem.Key] = (e.NewItem.Value, v);
|
||||
filter.InvokeOnAdd(new KeyValuePair<TKey, TValue>(e.NewItem.Key, e.NewItem.Value), v, e);
|
||||
|
||||
filter.InvokeOnReplace(e.NewItem, v, e.OldItem, ov.Item2, -1);
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
{
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in dict)
|
||||
{
|
||||
filter.InvokeOnRemove((new KeyValuePair<TKey, TValue>(item.Key, item.Value.Item1), item.Value.Item2), e);
|
||||
}
|
||||
}
|
||||
|
||||
dict.Clear();
|
||||
filter.InvokeOnReset();
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Move: // ObservableDictionary have no Move operation.
|
||||
|
@ -51,8 +51,8 @@ namespace ObservableCollections
|
||||
dictionary[key] = value;
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<KeyValuePair<TKey, TValue>>.Replace(
|
||||
new KeyValuePair<TKey, TValue>(key, value),
|
||||
new KeyValuePair<TKey, TValue>(key, oldValue),
|
||||
-1));
|
||||
new KeyValuePair<TKey, TValue>(key, oldValue!),
|
||||
-1, -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var oldValue = buffer[index];
|
||||
buffer[index] = value;
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index));
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace ObservableCollections
|
||||
{
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd((value, view), NotifyCollectionChangedEventArgs<T>.Add(value, -1));
|
||||
filter.InvokeOnAdd((value, view), -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -130,15 +130,16 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
dict.Add(e.NewItem, v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = e.NewStartingIndex;
|
||||
foreach (var item in e.NewItems)
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
dict.Add(item, v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, i++);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -147,7 +148,7 @@ namespace ObservableCollections
|
||||
{
|
||||
if (dict.Remove(e.OldItem, out var value))
|
||||
{
|
||||
filter.InvokeOnRemove(value.Item1, value.Item2, e);
|
||||
filter.InvokeOnRemove(value, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -156,20 +157,14 @@ namespace ObservableCollections
|
||||
{
|
||||
if (dict.Remove(item, out var value))
|
||||
{
|
||||
filter.InvokeOnRemove(value.Item1, value.Item2, e);
|
||||
filter.InvokeOnRemove(value, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in dict)
|
||||
{
|
||||
filter.InvokeOnRemove(item.Value, e);
|
||||
}
|
||||
}
|
||||
dict.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
|
@ -71,8 +71,7 @@ namespace ObservableCollections
|
||||
var (value, view) = list[i];
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
var eventArgs = NotifyCollectionChangedEventArgs<T>.Add(value, i);
|
||||
filter.InvokeOnAdd(value, view, eventArgs);
|
||||
filter.InvokeOnAdd(value, view, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -153,15 +152,16 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
list.Add(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, e.NewStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = e.NewStartingIndex;
|
||||
foreach (var item in e.NewItems)
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
list.Add(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,18 +172,18 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
list.Insert(e.NewStartingIndex, v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, e.NewStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// inefficient copy, need refactoring
|
||||
var newArray = new (T, TView)[e.NewItems.Length];
|
||||
var span = e.NewItems;
|
||||
for (int i = 0; i < span.Length; i++)
|
||||
for (var i = 0; i < span.Length; i++)
|
||||
{
|
||||
var v = (span[i], selector(span[i]));
|
||||
newArray[i] = v;
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, e.NewStartingIndex + i);
|
||||
}
|
||||
list.InsertRange(e.NewStartingIndex, newArray);
|
||||
}
|
||||
@ -194,15 +194,15 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = list[e.OldStartingIndex];
|
||||
list.RemoveAt(e.OldStartingIndex);
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v, e.OldStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
var len = e.OldStartingIndex + e.OldItems.Length;
|
||||
for (int i = e.OldStartingIndex; i < len; i++)
|
||||
for (var i = e.OldStartingIndex; i < len; i++)
|
||||
{
|
||||
var v = list[i];
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v, e.OldStartingIndex + i);
|
||||
}
|
||||
|
||||
list.RemoveRange(e.OldStartingIndex, e.OldItems.Length);
|
||||
@ -212,12 +212,9 @@ namespace ObservableCollections
|
||||
// ObservableList does not support replace range
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
|
||||
var oldItem = list[e.NewStartingIndex];
|
||||
var ov = (e.OldItem, selector(e.OldItem));
|
||||
list[e.NewStartingIndex] = v;
|
||||
|
||||
filter.InvokeOnRemove(oldItem, e);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnReplace(v, ov, e.NewStartingIndex);
|
||||
break;
|
||||
}
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
@ -226,18 +223,12 @@ namespace ObservableCollections
|
||||
list.RemoveAt(e.OldStartingIndex);
|
||||
list.Insert(e.NewStartingIndex, removeItem);
|
||||
|
||||
filter.InvokeOnMove(removeItem, e);
|
||||
filter.InvokeOnMove(removeItem, e.NewStartingIndex, e.OldStartingIndex);
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
filter.InvokeOnRemove(item, e);
|
||||
}
|
||||
}
|
||||
list.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -10,7 +10,7 @@ namespace ObservableCollections
|
||||
public sealed partial class ObservableList<T> : IList<T>, IReadOnlyList<T>, IObservableCollection<T>
|
||||
{
|
||||
readonly List<T> list;
|
||||
public object SyncRoot { get; } = new object();
|
||||
public object SyncRoot { get; } = new();
|
||||
|
||||
public ObservableList()
|
||||
{
|
||||
@ -42,7 +42,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var oldValue = list[index];
|
||||
list[index] = value;
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index));
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +68,12 @@ namespace ObservableCollections
|
||||
{
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, i));
|
||||
filter.InvokeOnAdd(value, view, i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter.InvokeOnAttach(value, view);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,15 +147,16 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
queue.Enqueue(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, e.NewStartingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = e.NewStartingIndex;
|
||||
foreach (var item in e.NewItems)
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
queue.Enqueue(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, i++);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -165,7 +165,7 @@ namespace ObservableCollections
|
||||
if (e.IsSingleItem)
|
||||
{
|
||||
var v = queue.Dequeue();
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -173,19 +173,13 @@ namespace ObservableCollections
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
var v = queue.Dequeue();
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in queue)
|
||||
{
|
||||
filter.InvokeOnRemove(item, e);
|
||||
}
|
||||
}
|
||||
queue.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
|
@ -69,7 +69,7 @@ namespace ObservableCollections
|
||||
var (value, view) = ringBuffer[i];
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, i));
|
||||
filter.InvokeOnAdd(value, view, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -154,7 +154,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
ringBuffer.AddFirst(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -162,7 +162,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
ringBuffer.AddFirst(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
ringBuffer.AddLast(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, ringBuffer.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -181,7 +181,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
ringBuffer.AddLast(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, ringBuffer.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,14 +194,14 @@ namespace ObservableCollections
|
||||
if (e.IsSingleItem)
|
||||
{
|
||||
var v = ringBuffer.RemoveFirst();
|
||||
filter.InvokeOnRemove(v, e);
|
||||
filter.InvokeOnRemove(v, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < e.OldItems.Length; i++)
|
||||
{
|
||||
var v = ringBuffer.RemoveFirst();
|
||||
filter.InvokeOnRemove(v, e);
|
||||
filter.InvokeOnRemove(v, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,39 +210,32 @@ namespace ObservableCollections
|
||||
// RemoveLast
|
||||
if (e.IsSingleItem)
|
||||
{
|
||||
var index = ringBuffer.Count - 1;
|
||||
var v = ringBuffer.RemoveLast();
|
||||
filter.InvokeOnRemove(v, e);
|
||||
filter.InvokeOnRemove(v, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < e.OldItems.Length; i++)
|
||||
{
|
||||
var index = ringBuffer.Count - 1;
|
||||
var v = ringBuffer.RemoveLast();
|
||||
filter.InvokeOnRemove(v, e);
|
||||
filter.InvokeOnRemove(v, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in ringBuffer)
|
||||
{
|
||||
filter.InvokeOnRemove(item, e);
|
||||
}
|
||||
}
|
||||
ringBuffer.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
// range is not supported
|
||||
{
|
||||
var ov = ringBuffer[e.OldStartingIndex];
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
|
||||
var oldItem = ringBuffer[e.NewStartingIndex];
|
||||
ringBuffer[e.NewStartingIndex] = v;
|
||||
|
||||
filter.InvokeOnRemove(oldItem, e);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnReplace(v, ov, e.NewStartingIndex);
|
||||
break;
|
||||
}
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
|
@ -41,7 +41,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var oldValue = buffer[index];
|
||||
buffer[index] = value;
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index));
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,18 +63,16 @@ namespace ObservableCollections
|
||||
lock (SyncRoot)
|
||||
{
|
||||
this.filter = filter;
|
||||
var i = 0;
|
||||
foreach (var (value, view) in stack)
|
||||
{
|
||||
if (invokeAddEventForCurrentElements)
|
||||
{
|
||||
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, i));
|
||||
filter.InvokeOnAdd(value, view, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter.InvokeOnAttach(value, view);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,7 +146,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (e.NewItem, selector(e.NewItem));
|
||||
stack.Push(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -156,7 +154,7 @@ namespace ObservableCollections
|
||||
{
|
||||
var v = (item, selector(item));
|
||||
stack.Push(v);
|
||||
filter.InvokeOnAdd(v, e);
|
||||
filter.InvokeOnAdd(v, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -165,7 +163,7 @@ namespace ObservableCollections
|
||||
if (e.IsSingleItem)
|
||||
{
|
||||
var v = stack.Pop();
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -173,19 +171,13 @@ namespace ObservableCollections
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
var v = stack.Pop();
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, e);
|
||||
filter.InvokeOnRemove(v.Item1, v.Item2, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
if (!filter.IsNullFilter())
|
||||
{
|
||||
foreach (var item in stack)
|
||||
{
|
||||
filter.InvokeOnRemove(item, e);
|
||||
}
|
||||
}
|
||||
stack.Clear();
|
||||
filter.InvokeOnReset();
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
|
@ -45,9 +45,8 @@ namespace ObservableCollections
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
var index = stack.Count;
|
||||
stack.Push(item);
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Add(item, index));
|
||||
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Add(item, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FluentAssertions;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
@ -126,33 +127,30 @@ namespace ObservableCollections.Tests
|
||||
filter3.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-40, -34, -12);
|
||||
|
||||
dict.Add(99, -100);
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
dict[10] = -1090;
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue.Value, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090, -12));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
dict.Remove(20);
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
dict.Clear();
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value))
|
||||
.OrderBy(x => x.Value)
|
||||
.Should().Equal((ChangedKind.Remove, -1090), (ChangedKind.Remove, -100), (ChangedKind.Remove, -53), (ChangedKind.Remove, -40), (ChangedKind.Remove, -34));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value))
|
||||
.OrderBy(x => x.Value)
|
||||
.Should().Equal((ChangedKind.Remove, -1090), (ChangedKind.Remove, -100), (ChangedKind.Remove, -53), (ChangedKind.Remove, -40), (ChangedKind.Remove, -34));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value))
|
||||
.OrderBy(x => x.Value)
|
||||
.Should().Equal((ChangedKind.Remove, -1090), (ChangedKind.Remove, -100), (ChangedKind.Remove, -53), (ChangedKind.Remove, -40), (ChangedKind.Remove, -34));
|
||||
filter1.CalledOnCollectionChanged.Select(x => x.Action)
|
||||
.Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
filter2.CalledOnCollectionChanged.Select(x => x.Action)
|
||||
.Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
filter3.CalledOnCollectionChanged.Select(x => x.Action)
|
||||
.Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -171,16 +169,16 @@ namespace ObservableCollections.Tests
|
||||
view1.AttachFilter(filter1, true);
|
||||
|
||||
filter1.CalledOnCollectionChanged.Count.Should().Be(5);
|
||||
filter1.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[0].value.Key.Should().Be(10);
|
||||
filter1.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[1].value.Key.Should().Be(50);
|
||||
filter1.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[2].value.Key.Should().Be(30);
|
||||
filter1.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[3].value.Key.Should().Be(20);
|
||||
filter1.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[4].value.Key.Should().Be(40);
|
||||
filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[0].NewValue.Key.Should().Be(10);
|
||||
filter1.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[1].NewValue.Key.Should().Be(50);
|
||||
filter1.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[2].NewValue.Key.Should().Be(30);
|
||||
filter1.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[3].NewValue.Key.Should().Be(20);
|
||||
filter1.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[4].NewValue.Key.Should().Be(40);
|
||||
|
||||
filter1.CalledWhenTrue.Count.Should().Be(3);
|
||||
filter1.CalledWhenFalse.Count.Should().Be(2);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -69,12 +70,12 @@ namespace ObservableCollections.Tests
|
||||
set.Add(33);
|
||||
set.AddRange(new[] { 98 });
|
||||
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 33), (ChangedKind.Add, 98));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue)).Should().Equal((NotifyCollectionChangedAction.Add, 33), (NotifyCollectionChangedAction.Add, 98));
|
||||
filter.Clear();
|
||||
|
||||
set.Remove(10);
|
||||
set.RemoveRange(new[] { 50, 30 });
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Remove, 50), (ChangedKind.Remove, 30));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue)).Should().Equal((NotifyCollectionChangedAction.Remove, 10), (NotifyCollectionChangedAction.Remove, 50), (NotifyCollectionChangedAction.Remove, 30));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -92,16 +93,16 @@ namespace ObservableCollections.Tests
|
||||
|
||||
view.AttachFilter(filter, true);
|
||||
filter.CalledOnCollectionChanged.Count.Should().Be(5);
|
||||
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[0].value.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[1].value.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[2].value.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[3].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[4].value.Should().Be(40);
|
||||
filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[0].NewValue.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[1].NewValue.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[3].NewValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[4].NewValue.Should().Be(40);
|
||||
|
||||
filter.CalledWhenTrue.Count.Should().Be(1);
|
||||
filter.CalledWhenFalse.Count.Should().Be(4);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FluentAssertions;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
@ -178,45 +179,45 @@ namespace ObservableCollections.Tests
|
||||
filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101);
|
||||
filter3.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101);
|
||||
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 100), (ChangedKind.Add, 101));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 100), (ChangedKind.Add, 101));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 100), (ChangedKind.Add, 101));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 100, 7), (NotifyCollectionChangedAction.Add, 101, 8));
|
||||
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
list.Insert(0, 1000);
|
||||
list.InsertRange(0, new[] { 999 });
|
||||
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 0), (NotifyCollectionChangedAction.Add, 999, 0));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 1000, 9), (NotifyCollectionChangedAction.Add, 999, 9)); // sorted index
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
list.RemoveAt(0);
|
||||
list.RemoveRange(0, 1);
|
||||
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 0), (NotifyCollectionChangedAction.Remove, 1000, 0));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 999, 9), (NotifyCollectionChangedAction.Remove, 1000, 9));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
list[0] = 9999;
|
||||
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 0, 0));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999, 8, 0));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
list.Move(3, 0);
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44));
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 0, 3));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Move, 44, 2, 2));
|
||||
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
|
||||
|
||||
list.Clear();
|
||||
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 44), (ChangedKind.Remove, 9999), (ChangedKind.Remove, 21), (ChangedKind.Remove, 30), (ChangedKind.Remove, 45), (ChangedKind.Remove, 66), (ChangedKind.Remove, 90), (ChangedKind.Remove, 100), (ChangedKind.Remove, 101));
|
||||
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 21), (ChangedKind.Remove, 30), (ChangedKind.Remove, 44), (ChangedKind.Remove, 45), (ChangedKind.Remove, 66), (ChangedKind.Remove, 90), (ChangedKind.Remove, 100), (ChangedKind.Remove, 101), (ChangedKind.Remove, 9999));
|
||||
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 21), (ChangedKind.Remove, 30), (ChangedKind.Remove, 44), (ChangedKind.Remove, 45), (ChangedKind.Remove, 66), (ChangedKind.Remove, 90), (ChangedKind.Remove, 100), (ChangedKind.Remove, 101), (ChangedKind.Remove, 9999));
|
||||
filter1.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
filter2.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
filter3.CalledOnCollectionChanged.Select(x => x.Action).Should().Equal(NotifyCollectionChangedAction.Reset);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -229,14 +230,14 @@ namespace ObservableCollections.Tests
|
||||
var filter1 = new TestFilter<int>((x, v) => x % 2 == 0);
|
||||
view1.AttachFilter(filter1, true);
|
||||
|
||||
filter1.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[0].value.Should().Be(10);
|
||||
filter1.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[1].value.Should().Be(21);
|
||||
filter1.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[2].value.Should().Be(30);
|
||||
filter1.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter1.CalledOnCollectionChanged[3].value.Should().Be(44);
|
||||
filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[0].NewValue.Should().Be(10);
|
||||
filter1.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[1].NewValue.Should().Be(21);
|
||||
filter1.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[2].NewValue.Should().Be(30);
|
||||
filter1.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter1.CalledOnCollectionChanged[3].NewValue.Should().Be(44);
|
||||
|
||||
filter1.CalledWhenTrue.Count.Should().Be(3);
|
||||
filter1.CalledWhenFalse.Count.Should().Be(1);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -73,12 +74,12 @@ namespace ObservableCollections.Tests
|
||||
queue.Enqueue(33);
|
||||
queue.EnqueueRange(new[] { 98 });
|
||||
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 33), (ChangedKind.Add, 98));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 33, 5), (NotifyCollectionChangedAction.Add, 98, 6));
|
||||
filter.Clear();
|
||||
|
||||
queue.Dequeue();
|
||||
queue.DequeueRange(2);
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Remove, 50), (ChangedKind.Remove, 30));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 10, 0), (NotifyCollectionChangedAction.Remove, 50, 0), (NotifyCollectionChangedAction.Remove, 30, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -97,16 +98,21 @@ namespace ObservableCollections.Tests
|
||||
view.AttachFilter(filter, true);
|
||||
|
||||
filter.CalledOnCollectionChanged.Count.Should().Be(5);
|
||||
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[0].value.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[1].value.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[2].value.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[3].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[4].value.Should().Be(40);
|
||||
filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[0].NewValue.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[1].NewValue.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[1].NewViewIndex.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(2);
|
||||
filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[3].NewValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[3].NewViewIndex.Should().Be(3);
|
||||
filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[4].NewValue.Should().Be(40);
|
||||
filter.CalledOnCollectionChanged[4].NewViewIndex.Should().Be(4);
|
||||
|
||||
filter.CalledWhenTrue.Count.Should().Be(1);
|
||||
filter.CalledWhenFalse.Count.Should().Be(4);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -73,12 +74,12 @@ namespace ObservableCollections.Tests
|
||||
stack.Push(33);
|
||||
stack.PushRange(new[] { 98 });
|
||||
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 33), (ChangedKind.Add, 98));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.NewValue, x.NewViewIndex)).Should().Equal((NotifyCollectionChangedAction.Add, 33, 0), (NotifyCollectionChangedAction.Add, 98, 0));
|
||||
filter.Clear();
|
||||
|
||||
stack.Pop();
|
||||
stack.PopRange(2);
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 98), (ChangedKind.Remove, 33), (ChangedKind.Remove, 40));
|
||||
filter.CalledOnCollectionChanged.Select(x => (x.Action, x.OldValue, x.OldViewIndex)).Should().Equal((NotifyCollectionChangedAction.Remove, 98, 0), (NotifyCollectionChangedAction.Remove, 33, 0), (NotifyCollectionChangedAction.Remove, 40, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -96,16 +97,21 @@ namespace ObservableCollections.Tests
|
||||
|
||||
view.AttachFilter(filter, true);
|
||||
filter.CalledOnCollectionChanged.Count.Should().Be(5);
|
||||
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[4].value.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[3].value.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[2].value.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[1].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[0].value.Should().Be(40);
|
||||
filter.CalledOnCollectionChanged[4].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[4].NewValue.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[4].NewViewIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[3].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[3].NewValue.Should().Be(50);
|
||||
filter.CalledOnCollectionChanged[3].NewViewIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[2].NewValue.Should().Be(30);
|
||||
filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[1].NewValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[1].NewViewIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[0].NewValue.Should().Be(40);
|
||||
filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(0);
|
||||
|
||||
filter.CalledWhenTrue.Count.Should().Be(1);
|
||||
filter.CalledWhenFalse.Count.Should().Be(4);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace ObservableCollections.Tests;
|
||||
|
||||
@ -49,21 +50,21 @@ public class SortedViewTest
|
||||
sortedView.AttachFilter(filter);
|
||||
|
||||
list.Add(20);
|
||||
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[0].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[0].index.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[0].NewValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[0].NewView.Should().Be(new ViewContainer<int>(20));
|
||||
filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(1);
|
||||
|
||||
list.Remove(20);
|
||||
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Remove);
|
||||
filter.CalledOnCollectionChanged[1].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Remove);
|
||||
filter.CalledOnCollectionChanged[1].OldValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[1].OldView.Should().Be(new ViewContainer<int>(20));
|
||||
filter.CalledOnCollectionChanged[1].OldViewIndex.Should().Be(1);
|
||||
|
||||
list[1] = 999; // from 10(at 0 in original) to 999
|
||||
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Remove);
|
||||
filter.CalledOnCollectionChanged[2].value.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[2].oldIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[3].value.Should().Be(999);
|
||||
filter.CalledOnCollectionChanged[3].index.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Replace);
|
||||
filter.CalledOnCollectionChanged[2].NewValue.Should().Be(999);
|
||||
filter.CalledOnCollectionChanged[2].OldValue.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(1);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace ObservableCollections.Tests;
|
||||
|
||||
@ -49,21 +50,24 @@ public class SortedViewViewComparerTest
|
||||
sortedView.AttachFilter(filter);
|
||||
|
||||
list.Add(20);
|
||||
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[0].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[0].index.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
|
||||
filter.CalledOnCollectionChanged[0].NewValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[0].NewView.Should().Be(new ViewContainer<int>(20));
|
||||
filter.CalledOnCollectionChanged[0].NewViewIndex.Should().Be(1);
|
||||
|
||||
list.Remove(20);
|
||||
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Remove);
|
||||
filter.CalledOnCollectionChanged[1].value.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[1].Action.Should().Be(NotifyCollectionChangedAction.Remove);
|
||||
filter.CalledOnCollectionChanged[1].OldValue.Should().Be(20);
|
||||
filter.CalledOnCollectionChanged[1].OldView.Should().Be(new ViewContainer<int>(20));
|
||||
filter.CalledOnCollectionChanged[1].OldViewIndex.Should().Be(1);
|
||||
|
||||
list[1] = 999; // from 10(at 0 in original) to 999
|
||||
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Remove);
|
||||
filter.CalledOnCollectionChanged[2].value.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[2].oldIndex.Should().Be(0);
|
||||
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add);
|
||||
filter.CalledOnCollectionChanged[3].value.Should().Be(999);
|
||||
filter.CalledOnCollectionChanged[3].index.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[2].Action.Should().Be(NotifyCollectionChangedAction.Replace);
|
||||
filter.CalledOnCollectionChanged[2].NewValue.Should().Be(999);
|
||||
filter.CalledOnCollectionChanged[2].OldValue.Should().Be(10);
|
||||
filter.CalledOnCollectionChanged[2].NewView.Should().Be(new ViewContainer<int>(999));
|
||||
filter.CalledOnCollectionChanged[2].OldView.Should().Be(new ViewContainer<int>(10));
|
||||
filter.CalledOnCollectionChanged[2].NewViewIndex.Should().Be(1);
|
||||
filter.CalledOnCollectionChanged[2].OldViewIndex.Should().Be(0);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace ObservableCollections.Tests
|
||||
{
|
||||
@ -12,7 +13,7 @@ namespace ObservableCollections.Tests
|
||||
|
||||
public T Value { get; }
|
||||
|
||||
public static implicit operator ViewContainer<T>(T value) => new ViewContainer<T>(value);
|
||||
public static implicit operator ViewContainer<T>(T value) => new(value);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
@ -35,7 +36,7 @@ namespace ObservableCollections.Tests
|
||||
readonly Func<T, ViewContainer<T>, bool> filter;
|
||||
public List<(T, ViewContainer<T>)> CalledWhenTrue = new();
|
||||
public List<(T, ViewContainer<T>)> CalledWhenFalse = new();
|
||||
public List<(ChangedKind changedKind, T value, ViewContainer<T> view, int index, int oldIndex)> CalledOnCollectionChanged = new();
|
||||
public List<SynchronizedViewChangedEventArgs<T, ViewContainer<T>>> CalledOnCollectionChanged = new();
|
||||
|
||||
public TestFilter(Func<T, ViewContainer<T>, bool> filter)
|
||||
{
|
||||
@ -54,9 +55,9 @@ namespace ObservableCollections.Tests
|
||||
return this.filter.Invoke(value, view);
|
||||
}
|
||||
|
||||
public void OnCollectionChanged(ChangedKind changedKind, T value, ViewContainer<T> view, in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, ViewContainer<T>> args)
|
||||
{
|
||||
CalledOnCollectionChanged.Add((changedKind, value, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex));
|
||||
CalledOnCollectionChanged.Add(args);
|
||||
}
|
||||
|
||||
public void WhenTrue(T value, ViewContainer<T> view)
|
||||
@ -75,7 +76,7 @@ namespace ObservableCollections.Tests
|
||||
readonly Func<KeyValuePair<T, T>, ViewContainer<T>, bool> filter;
|
||||
public List<(KeyValuePair<T, T>, ViewContainer<T>)> CalledWhenTrue = new();
|
||||
public List<(KeyValuePair<T, T>, ViewContainer<T>)> CalledWhenFalse = new();
|
||||
public List<(ChangedKind changedKind, KeyValuePair<T, T> value, ViewContainer<T> view)> CalledOnCollectionChanged = new();
|
||||
public List<SynchronizedViewChangedEventArgs<KeyValuePair<T, T>, ViewContainer<T>>> CalledOnCollectionChanged = new();
|
||||
|
||||
public TestFilter2(Func<KeyValuePair<T, T>, ViewContainer<T>, bool> filter)
|
||||
{
|
||||
@ -94,9 +95,9 @@ namespace ObservableCollections.Tests
|
||||
return this.filter.Invoke(value, view);
|
||||
}
|
||||
|
||||
public void OnCollectionChanged(ChangedKind changedKind, KeyValuePair<T, T> value, ViewContainer<T> view, in NotifyCollectionChangedEventArgs<KeyValuePair<T, T>> eventArgs)
|
||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<KeyValuePair<T, T>, ViewContainer<T>> args)
|
||||
{
|
||||
CalledOnCollectionChanged.Add((changedKind, value, view));
|
||||
CalledOnCollectionChanged.Add(args);
|
||||
}
|
||||
|
||||
public void WhenTrue(KeyValuePair<T, T> value, ViewContainer<T> view)
|
||||
|
Loading…
x
Reference in New Issue
Block a user