Use NotifyCollectionChangedAction instead of ChangeKind

This commit is contained in:
hadashiA 2024-02-22 12:47:19 +09:00
parent bdbb5c0c76
commit 8da9587cba
24 changed files with 163 additions and 211 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Specialized;
using R3; using R3;
using System.Linq; using System.Linq;
using ObservableCollections; using ObservableCollections;
@ -65,24 +66,29 @@ class HogeFilter : ISynchronizedViewFilter<int, ViewModel>
} }
public void OnCollectionChanged( public void OnCollectionChanged(
ChangedKind changedKind, NotifyCollectionChangedAction changedAction,
int value, int value,
ViewModel view, ViewModel view,
in NotifyCollectionChangedEventArgs<int> eventArgs) in NotifyCollectionChangedEventArgs<int> eventArgs)
{ {
switch (changedKind) switch (changedAction)
{ {
case ChangedKind.Add: case NotifyCollectionChangedAction.Add:
view.Value += " Add"; view.Value += " Add";
break; break;
case ChangedKind.Remove: case NotifyCollectionChangedAction.Remove:
view.Value += " Remove"; view.Value += " Remove";
break; break;
case ChangedKind.Move: case NotifyCollectionChangedAction.Move:
view.Value += $" Move {eventArgs.OldStartingIndex} {eventArgs.NewStartingIndex}"; view.Value += $" Move {eventArgs.OldStartingIndex} {eventArgs.NewStartingIndex}";
break; break;
case NotifyCollectionChangedAction.Replace:
view.Value += $" Replace {eventArgs.OldStartingIndex} {eventArgs.NewStartingIndex}";
break;
case NotifyCollectionChangedAction.Reset:
break;
default: default:
throw new ArgumentOutOfRangeException(nameof(changedKind), changedKind, null); throw new ArgumentOutOfRangeException(nameof(changedAction), changedAction, null);
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Specialized;
namespace ObservableCollections namespace ObservableCollections
{ {
@ -7,12 +8,7 @@ namespace ObservableCollections
bool IsMatch(T value, TView view); bool IsMatch(T value, TView view);
void WhenTrue(T value, TView view); void WhenTrue(T value, TView view);
void WhenFalse(T value, TView view); void WhenFalse(T value, TView view);
void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs); void OnCollectionChanged(NotifyCollectionChangedAction changedAction, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs);
}
public enum ChangedKind
{
Add, Remove, Move
} }
public class SynchronizedViewFilter<T, TView> : ISynchronizedViewFilter<T, TView> public class SynchronizedViewFilter<T, TView> : ISynchronizedViewFilter<T, TView>
@ -22,9 +18,9 @@ namespace ObservableCollections
readonly Func<T, TView, bool> isMatch; readonly Func<T, TView, bool> isMatch;
readonly Action<T, TView>? whenTrue; readonly Action<T, TView>? whenTrue;
readonly Action<T, TView>? whenFalse; readonly Action<T, TView>? whenFalse;
readonly Action<ChangedKind, T, TView>? onCollectionChanged; readonly Action<NotifyCollectionChangedAction, T, TView>? onCollectionChanged;
public SynchronizedViewFilter(Func<T, TView, bool> isMatch, Action<T, TView>? whenTrue, Action<T, TView>? whenFalse, Action<ChangedKind, T, TView>? onCollectionChanged) public SynchronizedViewFilter(Func<T, TView, bool> isMatch, Action<T, TView>? whenTrue, Action<T, TView>? whenFalse, Action<NotifyCollectionChangedAction, T, TView>? onCollectionChanged)
{ {
this.isMatch = isMatch; this.isMatch = isMatch;
this.whenTrue = whenTrue; this.whenTrue = whenTrue;
@ -35,14 +31,15 @@ namespace ObservableCollections
public bool IsMatch(T value, TView view) => isMatch(value, view); public bool IsMatch(T value, TView view) => isMatch(value, view);
public void WhenFalse(T value, TView view) => whenFalse?.Invoke(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 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(NotifyCollectionChangedAction changedAction, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs) =>
onCollectionChanged?.Invoke(changedAction, value, view);
class NullViewFilter : ISynchronizedViewFilter<T, TView> class NullViewFilter : ISynchronizedViewFilter<T, TView>
{ {
public bool IsMatch(T value, TView view) => true; public bool IsMatch(T value, TView view) => true;
public void WhenFalse(T value, TView view) { } public void WhenFalse(T value, TView view) { }
public void WhenTrue(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(NotifyCollectionChangedAction changedAction, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs) { }
} }
} }
@ -58,7 +55,7 @@ namespace ObservableCollections
source.AttachFilter(new SynchronizedViewFilter<T, TView>(isMatch, whenTrue, whenFalse, null)); 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<NotifyCollectionChangedAction, T, TView>? onCollectionChanged)
{ {
source.AttachFilter(new SynchronizedViewFilter<T, TView>(isMatch, whenTrue, whenFalse, onCollectionChanged)); source.AttachFilter(new SynchronizedViewFilter<T, TView>(isMatch, whenTrue, whenFalse, onCollectionChanged));
} }
@ -83,7 +80,7 @@ namespace ObservableCollections
{ {
filter.WhenFalse(value, view); filter.WhenFalse(value, view);
} }
filter.OnCollectionChanged(ChangedKind.Add, value, view, eventArgs); filter.OnCollectionChanged(NotifyCollectionChangedAction.Add, value, view, eventArgs);
} }
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, in NotifyCollectionChangedEventArgs<T> eventArgs)
@ -93,7 +90,7 @@ namespace ObservableCollections
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, in NotifyCollectionChangedEventArgs<T> eventArgs)
{ {
filter.OnCollectionChanged(ChangedKind.Remove, value, view, eventArgs); filter.OnCollectionChanged(NotifyCollectionChangedAction.Remove, value, view, eventArgs);
} }
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, in NotifyCollectionChangedEventArgs<T> eventArgs)
@ -103,7 +100,22 @@ namespace ObservableCollections
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, in NotifyCollectionChangedEventArgs<T> eventArgs)
{ {
filter.OnCollectionChanged(ChangedKind.Move, value, view, eventArgs); filter.OnCollectionChanged(NotifyCollectionChangedAction.Move, value, view, eventArgs);
}
internal static void InvokeOnReplace<T, TView>(this ISynchronizedViewFilter<T, TView> filter, (T value, TView view) value, in NotifyCollectionChangedEventArgs<T> eventArgs)
{
InvokeOnReplace(filter, value.value, value.view, eventArgs);
}
internal static void InvokeOnReplace<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
{
filter.OnCollectionChanged(NotifyCollectionChangedAction.Replace, value, view, eventArgs);
}
internal static void InvokeOnReset<T, TView>(this ISynchronizedViewFilter<T, TView> filter, in NotifyCollectionChangedEventArgs<T> eventArgs)
{
filter.OnCollectionChanged(NotifyCollectionChangedAction.Reset, default!, default!, eventArgs);
} }
internal static void InvokeOnAttach<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view) internal static void InvokeOnAttach<T, TView>(this ISynchronizedViewFilter<T, TView> filter, T value, TView view)

View File

@ -58,25 +58,18 @@ namespace ObservableCollections.Internal
public void WhenTrue(T value, TView view) => currentFilter.WhenTrue(value, view); public void WhenTrue(T value, TView view) => currentFilter.WhenTrue(value, view);
public void WhenFalse(T value, TView view) => currentFilter.WhenFalse(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(NotifyCollectionChangedAction changedAction, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
{ {
currentFilter.OnCollectionChanged(changedKind, value, view, in eventArgs); currentFilter.OnCollectionChanged(changedAction, value, view, in eventArgs);
CollectionChanged?.Invoke(this, eventArgs.ToStandardEventArgs());
switch (changedKind) switch (changedAction)
{ {
case ChangedKind.Add: case NotifyCollectionChangedAction.Add:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, view, eventArgs.NewStartingIndex)); case NotifyCollectionChangedAction.Remove:
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs); case NotifyCollectionChangedAction.Reset:
return;
case ChangedKind.Remove:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, view, eventArgs.OldStartingIndex));
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs); PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
break; break;
case ChangedKind.Move:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex));
break;
default:
throw new ArgumentOutOfRangeException(nameof(changedKind), changedKind, null);
} }
} }
} }

View File

@ -185,11 +185,11 @@ namespace ObservableCollections.Internal
{ {
var oldValue = e.OldItem; var oldValue = e.OldItem;
var oldKey = (oldValue, identitySelector(oldValue)); var oldKey = (oldValue, identitySelector(oldValue));
var oldIndex = -1;
if (list.TryGetValue(oldKey, out var o)) if (list.TryGetValue(oldKey, out var o))
{ {
var oldIndex = list.IndexOfKey(oldKey); oldIndex = list.IndexOfKey(oldKey);
list.RemoveAt(oldIndex); list.RemoveAt(oldIndex);
filter.InvokeOnRemove(o, NotifyCollectionChangedEventArgs<T>.Remove(oldValue, oldIndex));
} }
var value = e.NewItem; var value = e.NewItem;
@ -198,7 +198,7 @@ namespace ObservableCollections.Internal
list.Add((value, id), (value, view)); list.Add((value, id), (value, view));
var newIndex = list.IndexOfKey((value, id)); var newIndex = list.IndexOfKey((value, id));
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, newIndex)); filter.InvokeOnReplace(value, view, NotifyCollectionChangedEventArgs<T>.Replace(e.NewItem, e.OldItem, newIndex, oldIndex));
} }
break; break;
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:
@ -212,14 +212,8 @@ namespace ObservableCollections.Internal
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in list)
{
filter.InvokeOnRemove(item.Value, e);
}
}
list.Clear(); list.Clear();
filter.InvokeOnReset(e);
break; break;
default: default:
break; break;

View File

@ -198,14 +198,14 @@ namespace ObservableCollections.Internal
{ {
var oldValue = e.OldItem; var oldValue = e.OldItem;
var oldId = identitySelector(oldValue); var oldId = identitySelector(oldValue);
var oldIndex = -1;
if (viewMap.Remove(oldId, out var oldView)) if (viewMap.Remove(oldId, out var oldView))
{ {
var oldKey = (oldView, oldId); var oldKey = (oldView, oldId);
if (list.TryGetValue(oldKey, out var v)) if (list.TryGetValue(oldKey, out var v))
{ {
var oldIndex = list.IndexOfKey(oldKey); oldIndex = list.IndexOfKey(oldKey);
list.RemoveAt(oldIndex); list.RemoveAt(oldIndex);
filter.InvokeOnRemove(oldValue, oldView, NotifyCollectionChangedEventArgs<T>.Remove(v.Value, oldIndex));
} }
} }
@ -216,7 +216,7 @@ namespace ObservableCollections.Internal
viewMap.Add(id, view); viewMap.Add(id, view);
var index = list.IndexOfKey((view, id)); var index = list.IndexOfKey((view, id));
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index)); filter.InvokeOnReplace(value, view, NotifyCollectionChangedEventArgs<T>.Replace(e.NewItem, e.OldItem, index, oldIndex));
break; break;
} }
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:
@ -231,15 +231,9 @@ namespace ObservableCollections.Internal
break; break;
} }
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in list)
{
filter.InvokeOnRemove(item.Value, e);
}
}
list.Clear(); list.Clear();
viewMap.Clear(); viewMap.Clear();
filter.InvokeOnReset(e);
break; break;
default: default:
break; break;

View File

@ -104,14 +104,14 @@ namespace ObservableCollections
return new NotifyCollectionChangedEventArgs<T>(NotifyCollectionChangedAction.Remove, false, oldItems: oldItems, oldStartingIndex: oldStartingIndex); 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) public static NotifyCollectionChangedEventArgs<T> Move(T changedItem, int newStartingIndex, int oldStartingIndex)

View File

@ -148,27 +148,17 @@ namespace ObservableCollections
break; break;
case NotifyCollectionChangedAction.Replace: 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); var v = selector(e.NewItem);
dict.Remove(e.OldItem.Key);
dict[e.NewItem.Key] = (e.NewItem.Value, v); dict[e.NewItem.Key] = (e.NewItem.Value, v);
filter.InvokeOnAdd(new KeyValuePair<TKey, TValue>(e.NewItem.Key, e.NewItem.Value), v, e);
filter.InvokeOnReplace(new KeyValuePair<TKey, TValue>(e.NewItem.Key, e.NewItem.Value), v, e);
} }
break; break;
case NotifyCollectionChangedAction.Reset: 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(); dict.Clear();
filter.InvokeOnReset(e);
} }
break; break;
case NotifyCollectionChangedAction.Move: // ObservableDictionary have no Move operation. case NotifyCollectionChangedAction.Move: // ObservableDictionary have no Move operation.

View File

@ -51,8 +51,8 @@ namespace ObservableCollections
dictionary[key] = value; dictionary[key] = value;
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<KeyValuePair<TKey, TValue>>.Replace( CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<KeyValuePair<TKey, TValue>>.Replace(
new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, value),
new KeyValuePair<TKey, TValue>(key, oldValue), new KeyValuePair<TKey, TValue>(key, oldValue!),
-1)); -1, -1));
} }
else else
{ {

View File

@ -51,7 +51,7 @@ namespace ObservableCollections
{ {
var oldValue = buffer[index]; var oldValue = buffer[index];
buffer[index] = value; buffer[index] = value;
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index)); CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
} }
} }
} }

View File

@ -162,14 +162,8 @@ namespace ObservableCollections
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in dict)
{
filter.InvokeOnRemove(item.Value, e);
}
}
dict.Clear(); dict.Clear();
filter.InvokeOnReset(e);
break; break;
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:

View File

@ -212,12 +212,8 @@ namespace ObservableCollections
// ObservableList does not support replace range // ObservableList does not support replace range
{ {
var v = (e.NewItem, selector(e.NewItem)); var v = (e.NewItem, selector(e.NewItem));
var oldItem = list[e.NewStartingIndex];
list[e.NewStartingIndex] = v; list[e.NewStartingIndex] = v;
filter.InvokeOnReplace(v, e);
filter.InvokeOnRemove(oldItem, e);
filter.InvokeOnAdd(v, e);
break; break;
} }
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:
@ -230,14 +226,8 @@ namespace ObservableCollections
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in list)
{
filter.InvokeOnRemove(item, e);
}
}
list.Clear(); list.Clear();
filter.InvokeOnReset(e);
break; break;
default: default:
break; break;

View File

@ -10,7 +10,7 @@ namespace ObservableCollections
public sealed partial class ObservableList<T> : IList<T>, IReadOnlyList<T>, IObservableCollection<T> public sealed partial class ObservableList<T> : IList<T>, IReadOnlyList<T>, IObservableCollection<T>
{ {
readonly List<T> list; readonly List<T> list;
public object SyncRoot { get; } = new object(); public object SyncRoot { get; } = new();
public ObservableList() public ObservableList()
{ {
@ -42,7 +42,7 @@ namespace ObservableCollections
{ {
var oldValue = list[index]; var oldValue = list[index];
list[index] = value; list[index] = value;
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index)); CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
} }
} }
} }

View File

@ -178,14 +178,8 @@ namespace ObservableCollections
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in queue)
{
filter.InvokeOnRemove(item, e);
}
}
queue.Clear(); queue.Clear();
filter.InvokeOnReset(e);
break; break;
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:

View File

@ -224,25 +224,15 @@ namespace ObservableCollections
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in ringBuffer)
{
filter.InvokeOnRemove(item, e);
}
}
ringBuffer.Clear(); ringBuffer.Clear();
filter.InvokeOnReset(e);
break; break;
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
// range is not supported // range is not supported
{ {
var v = (e.NewItem, selector(e.NewItem)); var v = (e.NewItem, selector(e.NewItem));
var oldItem = ringBuffer[e.NewStartingIndex];
ringBuffer[e.NewStartingIndex] = v; ringBuffer[e.NewStartingIndex] = v;
filter.InvokeOnReplace(v, e);
filter.InvokeOnRemove(oldItem, e);
filter.InvokeOnAdd(v, e);
break; break;
} }
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:

View File

@ -41,7 +41,7 @@ namespace ObservableCollections
{ {
var oldValue = buffer[index]; var oldValue = buffer[index];
buffer[index] = value; buffer[index] = value;
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index)); CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Replace(value, oldValue, index, index));
} }
} }
} }

View File

@ -178,14 +178,8 @@ namespace ObservableCollections
} }
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in stack)
{
filter.InvokeOnRemove(item, e);
}
}
stack.Clear(); stack.Clear();
filter.InvokeOnReset(e);
break; break;
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Move:

View File

@ -1,6 +1,7 @@
using FluentAssertions; using FluentAssertions;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Xunit; using Xunit;
@ -126,33 +127,30 @@ namespace ObservableCollections.Tests
filter3.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-40, -34, -12); filter3.CalledWhenTrue.Select(x => x.Item1.Value).Should().Equal(-40, -34, -12);
dict.Add(99, -100); dict.Add(99, -100);
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Add, -100)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Add, -100));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
dict[10] = -1090; dict[10] = -1090;
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -12), (ChangedKind.Add, -1090)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Replace, -1090));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
dict.Remove(20); dict.Remove(20);
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)).Should().Equal((ChangedKind.Remove, -25)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value.Value)).Should().Equal((NotifyCollectionChangedAction.Remove, -25));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
dict.Clear(); dict.Clear();
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)) filter1.CalledOnCollectionChanged.Select(x => x.changedAction)
.OrderBy(x => x.Value) .Should().Equal(NotifyCollectionChangedAction.Reset);
.Should().Equal((ChangedKind.Remove, -1090), (ChangedKind.Remove, -100), (ChangedKind.Remove, -53), (ChangedKind.Remove, -40), (ChangedKind.Remove, -34)); filter2.CalledOnCollectionChanged.Select(x => x.changedAction)
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value.Value)) .Should().Equal(NotifyCollectionChangedAction.Reset);
.OrderBy(x => x.Value) filter3.CalledOnCollectionChanged.Select(x => x.changedAction)
.Should().Equal((ChangedKind.Remove, -1090), (ChangedKind.Remove, -100), (ChangedKind.Remove, -53), (ChangedKind.Remove, -40), (ChangedKind.Remove, -34)); .Should().Equal(NotifyCollectionChangedAction.Reset);
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));
} }
[Fact] [Fact]
@ -171,15 +169,15 @@ namespace ObservableCollections.Tests
view1.AttachFilter(filter1, true); view1.AttachFilter(filter1, true);
filter1.CalledOnCollectionChanged.Count.Should().Be(5); filter1.CalledOnCollectionChanged.Count.Should().Be(5);
filter1.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[0].value.Key.Should().Be(10); filter1.CalledOnCollectionChanged[0].value.Key.Should().Be(10);
filter1.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[1].value.Key.Should().Be(50); filter1.CalledOnCollectionChanged[1].value.Key.Should().Be(50);
filter1.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[2].value.Key.Should().Be(30); filter1.CalledOnCollectionChanged[2].value.Key.Should().Be(30);
filter1.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[3].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[3].value.Key.Should().Be(20); filter1.CalledOnCollectionChanged[3].value.Key.Should().Be(20);
filter1.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[4].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[4].value.Key.Should().Be(40); filter1.CalledOnCollectionChanged[4].value.Key.Should().Be(40);
filter1.CalledWhenTrue.Count.Should().Be(3); filter1.CalledWhenTrue.Count.Should().Be(3);

View File

@ -1,6 +1,7 @@
using FluentAssertions; using FluentAssertions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -69,12 +70,12 @@ namespace ObservableCollections.Tests
set.Add(33); set.Add(33);
set.AddRange(new[] { 98 }); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 33), (NotifyCollectionChangedAction.Add, 98));
filter.Clear(); filter.Clear();
set.Remove(10); set.Remove(10);
set.RemoveRange(new[] { 50, 30 }); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 10), (NotifyCollectionChangedAction.Remove, 50), (NotifyCollectionChangedAction.Remove, 30));
} }
[Fact] [Fact]
@ -92,15 +93,15 @@ namespace ObservableCollections.Tests
view.AttachFilter(filter, true); view.AttachFilter(filter, true);
filter.CalledOnCollectionChanged.Count.Should().Be(5); filter.CalledOnCollectionChanged.Count.Should().Be(5);
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[0].value.Should().Be(10); filter.CalledOnCollectionChanged[0].value.Should().Be(10);
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[1].value.Should().Be(50); filter.CalledOnCollectionChanged[1].value.Should().Be(50);
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[2].value.Should().Be(30); filter.CalledOnCollectionChanged[2].value.Should().Be(30);
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[3].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[3].value.Should().Be(20); filter.CalledOnCollectionChanged[3].value.Should().Be(20);
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[4].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[4].value.Should().Be(40); filter.CalledOnCollectionChanged[4].value.Should().Be(40);
filter.CalledWhenTrue.Count.Should().Be(1); filter.CalledWhenTrue.Count.Should().Be(1);

View File

@ -1,6 +1,7 @@
using FluentAssertions; using FluentAssertions;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Xunit; using Xunit;
@ -178,45 +179,45 @@ namespace ObservableCollections.Tests
filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101); filter2.CalledWhenFalse.Select(x => x.Item1).Should().Equal(101);
filter3.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)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 100), (NotifyCollectionChangedAction.Add, 101));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 100), (ChangedKind.Add, 101)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 100), (NotifyCollectionChangedAction.Add, 101));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 100), (ChangedKind.Add, 101)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 100), (NotifyCollectionChangedAction.Add, 101));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
list.Insert(0, 1000); list.Insert(0, 1000);
list.InsertRange(0, new[] { 999 }); list.InsertRange(0, new[] { 999 });
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 1000), (NotifyCollectionChangedAction.Add, 999));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 1000), (NotifyCollectionChangedAction.Add, 999));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Add, 1000), (ChangedKind.Add, 999)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 1000), (NotifyCollectionChangedAction.Add, 999));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
list.RemoveAt(0); list.RemoveAt(0);
list.RemoveRange(0, 1); list.RemoveRange(0, 1);
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 999), (NotifyCollectionChangedAction.Remove, 1000));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 999), (NotifyCollectionChangedAction.Remove, 1000));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 999), (ChangedKind.Remove, 1000)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 999), (NotifyCollectionChangedAction.Remove, 1000));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
list[0] = 9999; list[0] = 9999;
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Remove, 10), (ChangedKind.Add, 9999)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Replace, 9999));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
list.Move(3, 0); list.Move(3, 0);
filter1.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44)); filter1.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Move, 44));
filter2.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44)); filter2.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Move, 44));
filter3.CalledOnCollectionChanged.Select(x => (x.changedKind, x.value)).Should().Equal((ChangedKind.Move, 44)); filter3.CalledOnCollectionChanged.Select(x => (x.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Move, 44));
foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear(); foreach (var item in new[] { filter1, filter2, filter3 }) item.CalledOnCollectionChanged.Clear();
list.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)); filter1.CalledOnCollectionChanged.Select(x => x.changedAction).Should().Equal(NotifyCollectionChangedAction.Reset);
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)); filter2.CalledOnCollectionChanged.Select(x => x.changedAction).Should().Equal(NotifyCollectionChangedAction.Reset);
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)); filter3.CalledOnCollectionChanged.Select(x => x.changedAction).Should().Equal(NotifyCollectionChangedAction.Reset);
} }
[Fact] [Fact]
@ -229,13 +230,13 @@ namespace ObservableCollections.Tests
var filter1 = new TestFilter<int>((x, v) => x % 2 == 0); var filter1 = new TestFilter<int>((x, v) => x % 2 == 0);
view1.AttachFilter(filter1, true); view1.AttachFilter(filter1, true);
filter1.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[0].value.Should().Be(10); filter1.CalledOnCollectionChanged[0].value.Should().Be(10);
filter1.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[1].value.Should().Be(21); filter1.CalledOnCollectionChanged[1].value.Should().Be(21);
filter1.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[2].value.Should().Be(30); filter1.CalledOnCollectionChanged[2].value.Should().Be(30);
filter1.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add); filter1.CalledOnCollectionChanged[3].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter1.CalledOnCollectionChanged[3].value.Should().Be(44); filter1.CalledOnCollectionChanged[3].value.Should().Be(44);
filter1.CalledWhenTrue.Count.Should().Be(3); filter1.CalledWhenTrue.Count.Should().Be(3);

View File

@ -1,6 +1,7 @@
using FluentAssertions; using FluentAssertions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -73,12 +74,12 @@ namespace ObservableCollections.Tests
queue.Enqueue(33); queue.Enqueue(33);
queue.EnqueueRange(new[] { 98 }); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 33), (NotifyCollectionChangedAction.Add, 98));
filter.Clear(); filter.Clear();
queue.Dequeue(); queue.Dequeue();
queue.DequeueRange(2); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 10), (NotifyCollectionChangedAction.Remove, 50), (NotifyCollectionChangedAction.Remove, 30));
} }
[Fact] [Fact]
@ -97,15 +98,15 @@ namespace ObservableCollections.Tests
view.AttachFilter(filter, true); view.AttachFilter(filter, true);
filter.CalledOnCollectionChanged.Count.Should().Be(5); filter.CalledOnCollectionChanged.Count.Should().Be(5);
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[0].value.Should().Be(10); filter.CalledOnCollectionChanged[0].value.Should().Be(10);
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[1].value.Should().Be(50); filter.CalledOnCollectionChanged[1].value.Should().Be(50);
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[2].value.Should().Be(30); filter.CalledOnCollectionChanged[2].value.Should().Be(30);
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[3].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[3].value.Should().Be(20); filter.CalledOnCollectionChanged[3].value.Should().Be(20);
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[4].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[4].value.Should().Be(40); filter.CalledOnCollectionChanged[4].value.Should().Be(40);
filter.CalledWhenTrue.Count.Should().Be(1); filter.CalledWhenTrue.Count.Should().Be(1);

View File

@ -1,6 +1,7 @@
using FluentAssertions; using FluentAssertions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -73,12 +74,12 @@ namespace ObservableCollections.Tests
stack.Push(33); stack.Push(33);
stack.PushRange(new[] { 98 }); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Add, 33), (NotifyCollectionChangedAction.Add, 98));
filter.Clear(); filter.Clear();
stack.Pop(); stack.Pop();
stack.PopRange(2); 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.changedAction, x.value)).Should().Equal((NotifyCollectionChangedAction.Remove, 98), (NotifyCollectionChangedAction.Remove, 33), (NotifyCollectionChangedAction.Remove, 40));
} }
[Fact] [Fact]
@ -96,15 +97,15 @@ namespace ObservableCollections.Tests
view.AttachFilter(filter, true); view.AttachFilter(filter, true);
filter.CalledOnCollectionChanged.Count.Should().Be(5); filter.CalledOnCollectionChanged.Count.Should().Be(5);
filter.CalledOnCollectionChanged[4].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[4].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[4].value.Should().Be(10); filter.CalledOnCollectionChanged[4].value.Should().Be(10);
filter.CalledOnCollectionChanged[3].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[3].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[3].value.Should().Be(50); filter.CalledOnCollectionChanged[3].value.Should().Be(50);
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[2].value.Should().Be(30); filter.CalledOnCollectionChanged[2].value.Should().Be(30);
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[1].value.Should().Be(20); filter.CalledOnCollectionChanged[1].value.Should().Be(20);
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[0].value.Should().Be(40); filter.CalledOnCollectionChanged[0].value.Should().Be(40);
filter.CalledWhenTrue.Count.Should().Be(1); filter.CalledWhenTrue.Count.Should().Be(1);

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
namespace ObservableCollections.Tests; namespace ObservableCollections.Tests;
@ -49,21 +50,19 @@ public class SortedViewTest
sortedView.AttachFilter(filter); sortedView.AttachFilter(filter);
list.Add(20); list.Add(20);
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[0].value.Should().Be(20); filter.CalledOnCollectionChanged[0].value.Should().Be(20);
filter.CalledOnCollectionChanged[0].index.Should().Be(1); filter.CalledOnCollectionChanged[0].index.Should().Be(1);
list.Remove(20); list.Remove(20);
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Remove); filter.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Remove);
filter.CalledOnCollectionChanged[1].value.Should().Be(20); filter.CalledOnCollectionChanged[1].value.Should().Be(20);
filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1); filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1);
list[1] = 999; // from 10(at 0 in original) to 999 list[1] = 999; // from 10(at 0 in original) to 999
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Remove); filter.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Replace);
filter.CalledOnCollectionChanged[2].value.Should().Be(10); filter.CalledOnCollectionChanged[2].value.Should().Be(999);
filter.CalledOnCollectionChanged[2].index.Should().Be(1);
filter.CalledOnCollectionChanged[2].oldIndex.Should().Be(0); 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);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
namespace ObservableCollections.Tests; namespace ObservableCollections.Tests;
@ -49,21 +50,19 @@ public class SortedViewViewComparerTest
sortedView.AttachFilter(filter); sortedView.AttachFilter(filter);
list.Add(20); list.Add(20);
filter.CalledOnCollectionChanged[0].changedKind.Should().Be(ChangedKind.Add); filter.CalledOnCollectionChanged[0].changedAction.Should().Be(NotifyCollectionChangedAction.Add);
filter.CalledOnCollectionChanged[0].value.Should().Be(20); filter.CalledOnCollectionChanged[0].value.Should().Be(20);
filter.CalledOnCollectionChanged[0].index.Should().Be(1); filter.CalledOnCollectionChanged[0].index.Should().Be(1);
list.Remove(20); list.Remove(20);
filter.CalledOnCollectionChanged[1].changedKind.Should().Be(ChangedKind.Remove); filter.CalledOnCollectionChanged[1].changedAction.Should().Be(NotifyCollectionChangedAction.Remove);
filter.CalledOnCollectionChanged[1].value.Should().Be(20); filter.CalledOnCollectionChanged[1].value.Should().Be(20);
filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1); filter.CalledOnCollectionChanged[1].oldIndex.Should().Be(1);
list[1] = 999; // from 10(at 0 in original) to 999 list[1] = 999; // from 10(at 0 in original) to 999
filter.CalledOnCollectionChanged[2].changedKind.Should().Be(ChangedKind.Remove); filter.CalledOnCollectionChanged[2].changedAction.Should().Be(NotifyCollectionChangedAction.Replace);
filter.CalledOnCollectionChanged[2].value.Should().Be(10); filter.CalledOnCollectionChanged[2].value.Should().Be(999);
filter.CalledOnCollectionChanged[2].index.Should().Be(1);
filter.CalledOnCollectionChanged[2].oldIndex.Should().Be(0); 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);
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
namespace ObservableCollections.Tests namespace ObservableCollections.Tests
{ {
@ -12,7 +13,7 @@ namespace ObservableCollections.Tests
public T Value { get; } 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() public override int GetHashCode()
{ {
@ -35,7 +36,7 @@ namespace ObservableCollections.Tests
readonly Func<T, ViewContainer<T>, bool> filter; readonly Func<T, ViewContainer<T>, bool> filter;
public List<(T, ViewContainer<T>)> CalledWhenTrue = new(); public List<(T, ViewContainer<T>)> CalledWhenTrue = new();
public List<(T, ViewContainer<T>)> CalledWhenFalse = 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<(NotifyCollectionChangedAction changedAction, T value, ViewContainer<T> view, int index, int oldIndex)> CalledOnCollectionChanged = new();
public TestFilter(Func<T, ViewContainer<T>, bool> filter) public TestFilter(Func<T, ViewContainer<T>, bool> filter)
{ {
@ -54,9 +55,9 @@ namespace ObservableCollections.Tests
return this.filter.Invoke(value, view); return this.filter.Invoke(value, view);
} }
public void OnCollectionChanged(ChangedKind changedKind, T value, ViewContainer<T> view, in NotifyCollectionChangedEventArgs<T> eventArgs) public void OnCollectionChanged(NotifyCollectionChangedAction changedAction, T value, ViewContainer<T> view, in NotifyCollectionChangedEventArgs<T> eventArgs)
{ {
CalledOnCollectionChanged.Add((changedKind, value, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex)); CalledOnCollectionChanged.Add((changedAction, value, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex));
} }
public void WhenTrue(T value, ViewContainer<T> view) public void WhenTrue(T value, ViewContainer<T> view)
@ -75,7 +76,7 @@ namespace ObservableCollections.Tests
readonly Func<KeyValuePair<T, T>, ViewContainer<T>, bool> filter; 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>)> CalledWhenTrue = new();
public List<(KeyValuePair<T, T>, ViewContainer<T>)> CalledWhenFalse = 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<(NotifyCollectionChangedAction changedAction, KeyValuePair<T, T> value, ViewContainer<T> view)> CalledOnCollectionChanged = new();
public TestFilter2(Func<KeyValuePair<T, T>, ViewContainer<T>, bool> filter) public TestFilter2(Func<KeyValuePair<T, T>, ViewContainer<T>, bool> filter)
{ {
@ -94,9 +95,9 @@ namespace ObservableCollections.Tests
return this.filter.Invoke(value, view); 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(NotifyCollectionChangedAction changedAction, KeyValuePair<T, T> value, ViewContainer<T> view, in NotifyCollectionChangedEventArgs<KeyValuePair<T, T>> eventArgs)
{ {
CalledOnCollectionChanged.Add((changedKind, value, view)); CalledOnCollectionChanged.Add((changedAction, value, view));
} }
public void WhenTrue(KeyValuePair<T, T> value, ViewContainer<T> view) public void WhenTrue(KeyValuePair<T, T> value, ViewContainer<T> view)