Fix (NotifyCollecitonChanged)SynchronizedViewList does not sync correcty when view is attached filter
This commit is contained in:
parent
b73a30c366
commit
0ce9b3a10e
@ -466,6 +466,11 @@ This is the interface for View:
|
|||||||
```csharp
|
```csharp
|
||||||
public delegate void NotifyViewChangedEventHandler<T, TView>(in SynchronizedViewChangedEventArgs<T, TView> e);
|
public delegate void NotifyViewChangedEventHandler<T, TView>(in SynchronizedViewChangedEventArgs<T, TView> e);
|
||||||
|
|
||||||
|
public enum RejectedViewChangedAction
|
||||||
|
{
|
||||||
|
Add, Remove, Move
|
||||||
|
}
|
||||||
|
|
||||||
public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisposable
|
public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisposable
|
||||||
{
|
{
|
||||||
object SyncRoot { get; }
|
object SyncRoot { get; }
|
||||||
@ -475,6 +480,7 @@ public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisp
|
|||||||
int UnfilteredCount { get; }
|
int UnfilteredCount { get; }
|
||||||
|
|
||||||
event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged; // int index, int oldIndex(when RejectedViewChangedAction is Move)
|
||||||
event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
void AttachFilter(ISynchronizedViewFilter<T> filter);
|
void AttachFilter(ISynchronizedViewFilter<T> filter);
|
||||||
|
@ -8,68 +8,80 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var buffer = new ObservableList<int>(5);
|
||||||
|
|
||||||
// Queue <-> List Synchronization
|
var view = buffer.CreateView(value => value);
|
||||||
var queue = new ObservableQueue<int>();
|
view.AttachFilter(value => value % 2 == 1); // when filtered, mismatch...!
|
||||||
|
|
||||||
queue.Enqueue(1);
|
//{
|
||||||
queue.Enqueue(10);
|
// INotifyCollectionChangedSynchronizedViewList created from ISynchronizedView with a filter.
|
||||||
queue.Enqueue(100);
|
var collection = view.ToNotifyCollectionChanged();
|
||||||
queue.Enqueue(1000);
|
|
||||||
queue.Enqueue(10000);
|
|
||||||
|
|
||||||
using var view = queue.CreateView(x => x.ToString() + "$");
|
// Not disposed here.
|
||||||
|
//}
|
||||||
|
|
||||||
using var viewList = view.ToViewList();
|
buffer.Insert(0, 1);
|
||||||
|
buffer.Insert(0, 1);
|
||||||
|
buffer.Insert(0, 2);
|
||||||
|
buffer.Insert(0, 3);
|
||||||
|
buffer.Insert(0, 5);
|
||||||
|
buffer.RemoveAt(buffer.Count - 1);
|
||||||
|
|
||||||
Console.WriteLine(viewList[2]); // 100$
|
buffer.Insert(0, 8);
|
||||||
|
buffer.Insert(0, 13);
|
||||||
|
|
||||||
|
|
||||||
view.ViewChanged += View_ViewChanged;
|
buffer.Move(1, 5);
|
||||||
|
|
||||||
void View_ViewChanged(in SynchronizedViewChangedEventArgs<int, string> eventArgs)
|
foreach (var item in view)
|
||||||
{
|
{
|
||||||
if (eventArgs.Action == NotifyCollectionChangedAction.Add)
|
Console.WriteLine(item);
|
||||||
|
}
|
||||||
|
Console.WriteLine("---");
|
||||||
|
|
||||||
|
foreach (var item in collection)
|
||||||
{
|
{
|
||||||
// eventArgs.OldItem.View.
|
|
||||||
|
Console.WriteLine(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewModel
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Value { get; set; } = default!;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HogeFilter : ISynchronizedViewFilter<int>
|
//var buffer = new ObservableFixedSizeRingBuffer<int>(5);
|
||||||
{
|
|
||||||
public bool IsMatch(int value)
|
|
||||||
{
|
|
||||||
return value % 2 == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCollectionChanged(in SynchronizedViewChangedEventArgs<int, ViewModel> eventArgs)
|
//var view = buffer.CreateView(value => value);
|
||||||
{
|
//view.AttachFilter(value => value % 2 == 1); // when filtered, mismatch...!
|
||||||
switch (eventArgs.Action)
|
|
||||||
{
|
////{
|
||||||
case NotifyCollectionChangedAction.Add:
|
//// INotifyCollectionChangedSynchronizedViewList created from ISynchronizedView with a filter.
|
||||||
eventArgs.NewItem.View.Value += " Add";
|
//var collection = view.ToNotifyCollectionChanged();
|
||||||
break;
|
|
||||||
case NotifyCollectionChangedAction.Remove:
|
//// Not disposed here.
|
||||||
eventArgs.OldItem.View.Value += " Remove";
|
////}
|
||||||
break;
|
|
||||||
case NotifyCollectionChangedAction.Move:
|
//buffer.AddFirst(1);
|
||||||
eventArgs.NewItem.View.Value += $" Move {eventArgs.OldStartingIndex} {eventArgs.NewStartingIndex}";
|
//buffer.AddFirst(1);
|
||||||
break;
|
//buffer.AddFirst(2);
|
||||||
case NotifyCollectionChangedAction.Replace:
|
//buffer.AddFirst(3);
|
||||||
eventArgs.NewItem.View.Value += $" Replace {eventArgs.NewStartingIndex}";
|
//buffer.AddFirst(5);
|
||||||
break;
|
//buffer.AddFirst(8); // Argument out of range
|
||||||
case NotifyCollectionChangedAction.Reset:
|
//buffer.AddFirst(13);
|
||||||
break;
|
|
||||||
default:
|
//foreach (var item in collection)
|
||||||
throw new ArgumentOutOfRangeException(nameof(eventArgs.Action), eventArgs.Action, null);
|
//{
|
||||||
}
|
// Console.WriteLine(item);
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
//Console.WriteLine("---");
|
||||||
|
|
||||||
|
//foreach (var item in view)
|
||||||
|
//{
|
||||||
|
// Console.WriteLine(item);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Console.WriteLine("---");
|
||||||
|
|
||||||
|
//foreach (var item in buffer)
|
||||||
|
//{
|
||||||
|
// Console.WriteLine(item);
|
||||||
|
//}
|
@ -3,7 +3,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@ -24,7 +23,7 @@ public class AlternateIndexList<T> : IEnumerable<T>
|
|||||||
this.list = values.Select(x => new IndexedValue(x.OrderedAlternateIndex, x.Value)).ToList();
|
this.list = values.Select(x => new IndexedValue(x.OrderedAlternateIndex, x.Value)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAlternateIndex(int startIndex, int incr)
|
public void UpdateAlternateIndex(int startIndex, int incr)
|
||||||
{
|
{
|
||||||
var span = CollectionsMarshal.AsSpan(list);
|
var span = CollectionsMarshal.AsSpan(list);
|
||||||
for (int i = startIndex; i < span.Length; i++)
|
for (int i = startIndex; i < span.Length; i++)
|
||||||
@ -80,11 +79,15 @@ public class AlternateIndexList<T> : IEnumerable<T>
|
|||||||
public int RemoveAt(int alternateIndex)
|
public int RemoveAt(int alternateIndex)
|
||||||
{
|
{
|
||||||
var index = list.BinarySearch(alternateIndex);
|
var index = list.BinarySearch(alternateIndex);
|
||||||
if (index != -1)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
list.RemoveAt(index);
|
list.RemoveAt(index);
|
||||||
UpdateAlternateIndex(index, -1);
|
UpdateAlternateIndex(index, -1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Index was not found. AlternateIndex:" + alternateIndex);
|
||||||
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +127,19 @@ public class AlternateIndexList<T> : IEnumerable<T>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryReplaceAlternateIndex(int getAlternateIndex, int setAlternateIndex)
|
||||||
|
{
|
||||||
|
var index = list.BinarySearch(getAlternateIndex);
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var span = CollectionsMarshal.AsSpan(list);
|
||||||
|
span[index].AlternateIndex = setAlternateIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryReplaceByValue(T searchValue, T replaceValue, out int replacedIndex)
|
public bool TryReplaceByValue(T searchValue, T replaceValue, out int replacedIndex)
|
||||||
{
|
{
|
||||||
replacedIndex = list.FindIndex(x => EqualityComparer<T>.Default.Equals(x.Value, searchValue));
|
replacedIndex = list.FindIndex(x => EqualityComparer<T>.Default.Equals(x.Value, searchValue));
|
||||||
|
@ -25,6 +25,11 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum RejectedViewChangedAction
|
||||||
|
{
|
||||||
|
Add, Remove, Move
|
||||||
|
}
|
||||||
|
|
||||||
public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisposable
|
public interface ISynchronizedView<T, TView> : IReadOnlyCollection<TView>, IDisposable
|
||||||
{
|
{
|
||||||
object SyncRoot { get; }
|
object SyncRoot { get; }
|
||||||
@ -34,6 +39,7 @@ namespace ObservableCollections
|
|||||||
int UnfilteredCount { get; }
|
int UnfilteredCount { get; }
|
||||||
|
|
||||||
event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
void AttachFilter(ISynchronizedViewFilter<T> filter);
|
void AttachFilter(ISynchronizedViewFilter<T> filter);
|
||||||
|
@ -39,6 +39,7 @@ namespace ObservableCollections
|
|||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
public event NotifyViewChangedEventHandler<KeyValuePair<TKey, TValue>, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<KeyValuePair<TKey, TValue>, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public ISynchronizedViewFilter<KeyValuePair<TKey, TValue>> Filter
|
public ISynchronizedViewFilter<KeyValuePair<TKey, TValue>> Filter
|
||||||
@ -184,14 +185,14 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = selector(e.NewItem);
|
var v = selector(e.NewItem);
|
||||||
dict.Add(e.NewItem.Key, (e.NewItem.Value, v));
|
dict.Add(e.NewItem.Key, (e.NewItem.Value, v));
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, e.NewItem, v, -1);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, e.NewItem, v, -1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Remove:
|
case NotifyCollectionChangedAction.Remove:
|
||||||
{
|
{
|
||||||
if (dict.Remove(e.OldItem.Key, out var v))
|
if (dict.Remove(e.OldItem.Key, out var v))
|
||||||
{
|
{
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, e.OldItem, v.Item2, -1);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, e.OldItem, v.Item2, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -30,6 +30,7 @@ namespace ObservableCollections
|
|||||||
ISynchronizedViewFilter<T> filter;
|
ISynchronizedViewFilter<T> filter;
|
||||||
|
|
||||||
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
@ -181,7 +182,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
dict.Add(e.NewItem, v);
|
dict.Add(e.NewItem, v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, -1);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -190,7 +191,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
dict.Add(item, v);
|
dict.Add(item, v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, i++);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -199,7 +200,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
if (dict.Remove(e.OldItem, out var value))
|
if (dict.Remove(e.OldItem, out var value))
|
||||||
{
|
{
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, value, -1);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, value, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -208,7 +209,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
if (dict.Remove(item, out var value))
|
if (dict.Remove(item, out var value))
|
||||||
{
|
{
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, value, -1);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, value, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ namespace ObservableCollections
|
|||||||
ISynchronizedViewFilter<T> filter;
|
ISynchronizedViewFilter<T> filter;
|
||||||
|
|
||||||
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
@ -185,7 +186,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
list.Insert(e.NewStartingIndex, v);
|
list.Insert(e.NewStartingIndex, v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, e.NewStartingIndex);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, e.NewStartingIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -214,7 +215,7 @@ namespace ObservableCollections
|
|||||||
}
|
}
|
||||||
|
|
||||||
list.InsertRange(e.NewStartingIndex, valueViews.Span);
|
list.InsertRange(e.NewStartingIndex, valueViews.Span);
|
||||||
this.InvokeOnAddRange(ViewChanged, e.NewItems, views.Span, isMatchAll, matches.Span, e.NewStartingIndex);
|
this.InvokeOnAddRange(ViewChanged, RejectedViewChanged, e.NewItems, views.Span, isMatchAll, matches.Span, e.NewStartingIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Remove:
|
case NotifyCollectionChangedAction.Remove:
|
||||||
@ -222,7 +223,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = list[e.OldStartingIndex];
|
var v = list[e.OldStartingIndex];
|
||||||
list.RemoveAt(e.OldStartingIndex);
|
list.RemoveAt(e.OldStartingIndex);
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v, e.OldStartingIndex);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v, e.OldStartingIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -251,7 +252,7 @@ namespace ObservableCollections
|
|||||||
}
|
}
|
||||||
|
|
||||||
list.RemoveRange(e.OldStartingIndex, e.OldItems.Length);
|
list.RemoveRange(e.OldStartingIndex, e.OldItems.Length);
|
||||||
this.InvokeOnRemoveRange(ViewChanged, values.Span, views.Span, isMatchAll, matches.Span, e.OldStartingIndex);
|
this.InvokeOnRemoveRange(ViewChanged, RejectedViewChanged, values.Span, views.Span, isMatchAll, matches.Span, e.OldStartingIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Replace:
|
case NotifyCollectionChangedAction.Replace:
|
||||||
@ -269,7 +270,7 @@ namespace ObservableCollections
|
|||||||
list.RemoveAt(e.OldStartingIndex);
|
list.RemoveAt(e.OldStartingIndex);
|
||||||
list.Insert(e.NewStartingIndex, removeItem);
|
list.Insert(e.NewStartingIndex, removeItem);
|
||||||
|
|
||||||
this.InvokeOnMove(ref filteredCount, ViewChanged, removeItem, e.NewStartingIndex, e.OldStartingIndex);
|
this.InvokeOnMove(ref filteredCount, ViewChanged, RejectedViewChanged, removeItem, e.NewStartingIndex, e.OldStartingIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Reset:
|
case NotifyCollectionChangedAction.Reset:
|
||||||
|
@ -25,6 +25,7 @@ namespace ObservableCollections
|
|||||||
ISynchronizedViewFilter<T> filter;
|
ISynchronizedViewFilter<T> filter;
|
||||||
|
|
||||||
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
@ -182,7 +183,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
queue.Enqueue(v);
|
queue.Enqueue(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, e.NewStartingIndex);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, e.NewStartingIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -191,7 +192,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
queue.Enqueue(v);
|
queue.Enqueue(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, i++);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -200,7 +201,7 @@ namespace ObservableCollections
|
|||||||
if (e.IsSingleItem)
|
if (e.IsSingleItem)
|
||||||
{
|
{
|
||||||
var v = queue.Dequeue();
|
var v = queue.Dequeue();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v.Item1, v.Item2, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v.Item1, v.Item2, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -208,7 +209,7 @@ namespace ObservableCollections
|
|||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
var v = queue.Dequeue();
|
var v = queue.Dequeue();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v.Item1, v.Item2, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v.Item1, v.Item2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -31,6 +31,7 @@ namespace ObservableCollections
|
|||||||
ISynchronizedViewFilter<T> filter;
|
ISynchronizedViewFilter<T> filter;
|
||||||
|
|
||||||
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
@ -196,7 +197,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
ringBuffer.AddFirst(v);
|
ringBuffer.AddFirst(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -204,7 +205,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
ringBuffer.AddFirst(v);
|
ringBuffer.AddFirst(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,7 +216,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
ringBuffer.AddLast(v);
|
ringBuffer.AddLast(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, ringBuffer.Count - 1);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, ringBuffer.Count - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -223,7 +224,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
ringBuffer.AddLast(v);
|
ringBuffer.AddLast(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, ringBuffer.Count - 1);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, ringBuffer.Count - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,14 +237,14 @@ namespace ObservableCollections
|
|||||||
if (e.IsSingleItem)
|
if (e.IsSingleItem)
|
||||||
{
|
{
|
||||||
var v = ringBuffer.RemoveFirst();
|
var v = ringBuffer.RemoveFirst();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < e.OldItems.Length; i++)
|
for (int i = 0; i < e.OldItems.Length; i++)
|
||||||
{
|
{
|
||||||
var v = ringBuffer.RemoveFirst();
|
var v = ringBuffer.RemoveFirst();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +255,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var index = ringBuffer.Count - 1;
|
var index = ringBuffer.Count - 1;
|
||||||
var v = ringBuffer.RemoveLast();
|
var v = ringBuffer.RemoveLast();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v, index);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v, index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -262,7 +263,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var index = ringBuffer.Count - 1;
|
var index = ringBuffer.Count - 1;
|
||||||
var v = ringBuffer.RemoveLast();
|
var v = ringBuffer.RemoveLast();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v, index);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ namespace ObservableCollections
|
|||||||
ISynchronizedViewFilter<T> filter;
|
ISynchronizedViewFilter<T> filter;
|
||||||
|
|
||||||
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
|
||||||
|
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
|
||||||
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
|
||||||
|
|
||||||
public object SyncRoot { get; }
|
public object SyncRoot { get; }
|
||||||
@ -187,7 +188,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (e.NewItem, selector(e.NewItem));
|
var v = (e.NewItem, selector(e.NewItem));
|
||||||
stack.Push(v);
|
stack.Push(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -195,7 +196,7 @@ namespace ObservableCollections
|
|||||||
{
|
{
|
||||||
var v = (item, selector(item));
|
var v = (item, selector(item));
|
||||||
stack.Push(v);
|
stack.Push(v);
|
||||||
this.InvokeOnAdd(ref filteredCount, ViewChanged, v, 0);
|
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -204,7 +205,7 @@ namespace ObservableCollections
|
|||||||
if (e.IsSingleItem)
|
if (e.IsSingleItem)
|
||||||
{
|
{
|
||||||
var v = stack.Pop();
|
var v = stack.Pop();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v.Item1, v.Item2, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v.Item1, v.Item2, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -212,7 +213,7 @@ namespace ObservableCollections
|
|||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
var v = stack.Pop();
|
var v = stack.Pop();
|
||||||
this.InvokeOnRemove(ref filteredCount, ViewChanged, v.Item1, v.Item2, 0);
|
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, v.Item1, v.Item2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -94,108 +94,108 @@ namespace ObservableCollections
|
|||||||
return filter == SynchronizedViewFilter<T>.Null;
|
return filter == SynchronizedViewFilter<T>.Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, (T value, TView view) value, int index)
|
internal static void InvokeOnAdd<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, (T value, TView view) value, int index)
|
||||||
{
|
{
|
||||||
InvokeOnAdd(collection, ref filteredCount, ev, value.value, value.view, index);
|
InvokeOnAdd(collection, ref filteredCount, ev, ev2, value.value, value.view, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InvokeOnAdd<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, T value, TView view, int index)
|
internal static void InvokeOnAdd<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, T value, TView view, int index)
|
||||||
{
|
{
|
||||||
var isMatch = collection.Filter.IsMatch(value);
|
var isMatch = collection.Filter.IsMatch(value);
|
||||||
if (isMatch)
|
if (isMatch)
|
||||||
{
|
{
|
||||||
filteredCount++;
|
filteredCount++;
|
||||||
if (ev != null)
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, true, newItem: (value, view), newStartingIndex: index));
|
||||||
{
|
}
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, true, newItem: (value, view), newStartingIndex: index));
|
else
|
||||||
}
|
{
|
||||||
}
|
ev2?.Invoke(RejectedViewChangedAction.Add, index, -1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
internal static void InvokeOnAddRange<T, TView>(this ISynchronizedView<T, TView> collection, NotifyViewChangedEventHandler<T, TView>? ev, ReadOnlySpan<T> values, ReadOnlySpan<TView> views, bool isMatchAll, ReadOnlySpan<bool> matches, int index)
|
|
||||||
{
|
internal static void InvokeOnAddRange<T, TView>(this ISynchronizedView<T, TView> collection, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, ReadOnlySpan<T> values, ReadOnlySpan<TView> views, bool isMatchAll, ReadOnlySpan<bool> matches, int index)
|
||||||
if (ev != null)
|
{
|
||||||
{
|
if (isMatchAll)
|
||||||
if (isMatchAll)
|
{
|
||||||
{
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, isSingleItem: false, newValues: values, newViews: views, newStartingIndex: index));
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, isSingleItem: false, newValues: values, newViews: views, newStartingIndex: index));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var startingIndex = index;
|
|
||||||
for (var i = 0; i < matches.Length; i++)
|
for (var i = 0; i < matches.Length; i++)
|
||||||
{
|
{
|
||||||
if (matches[i])
|
if (matches[i])
|
||||||
{
|
{
|
||||||
var item = (values[i], views[i]);
|
var item = (values[i], views[i]);
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, isSingleItem: true, newItem: item, newStartingIndex: startingIndex++));
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, isSingleItem: true, newItem: item, newStartingIndex: index));
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, (T value, TView view) value, int oldIndex)
|
|
||||||
{
|
{
|
||||||
InvokeOnRemove(collection, ref filteredCount, ev, value.value, value.view, oldIndex);
|
ev2?.Invoke(RejectedViewChangedAction.Add, index, -1);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InvokeOnRemove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, T value, TView view, int oldIndex)
|
internal static void InvokeOnRemove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, (T value, TView view) value, int oldIndex)
|
||||||
|
{
|
||||||
|
InvokeOnRemove(collection, ref filteredCount, ev, ev2, value.value, value.view, oldIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void InvokeOnRemove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, T value, TView view, int oldIndex)
|
||||||
{
|
{
|
||||||
var isMatch = collection.Filter.IsMatch(value);
|
var isMatch = collection.Filter.IsMatch(value);
|
||||||
if (isMatch)
|
if (isMatch)
|
||||||
{
|
{
|
||||||
filteredCount--;
|
filteredCount--;
|
||||||
if (ev != null)
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, true, oldItem: (value, view), oldStartingIndex: oldIndex));
|
||||||
{
|
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, true, oldItem: (value, view), oldStartingIndex: oldIndex));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev2?.Invoke(RejectedViewChangedAction.Remove, oldIndex, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only use for ObservableList
|
// only use for ObservableList
|
||||||
internal static void InvokeOnRemoveRange<T, TView>(this ISynchronizedView<T, TView> collection, NotifyViewChangedEventHandler<T, TView>? ev, ReadOnlySpan<T> values, ReadOnlySpan<TView> views, bool isMatchAll, ReadOnlySpan<bool> matches, int index)
|
internal static void InvokeOnRemoveRange<T, TView>(this ISynchronizedView<T, TView> collection, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, ReadOnlySpan<T> values, ReadOnlySpan<TView> views, bool isMatchAll, ReadOnlySpan<bool> matches, int index)
|
||||||
{
|
|
||||||
if (ev != null)
|
|
||||||
{
|
{
|
||||||
if (isMatchAll)
|
if (isMatchAll)
|
||||||
{
|
{
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, isSingleItem: false, oldValues: values, oldViews: views, oldStartingIndex: index));
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, isSingleItem: false, oldValues: values, oldViews: views, oldStartingIndex: index));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var startingIndex = index;
|
|
||||||
for (var i = 0; i < matches.Length; i++)
|
for (var i = 0; i < matches.Length; i++)
|
||||||
{
|
{
|
||||||
if (matches[i])
|
if (matches[i])
|
||||||
{
|
{
|
||||||
var item = (values[i], views[i]);
|
var item = (values[i], views[i]);
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, isSingleItem: true, oldItem: item, oldStartingIndex: index)); //remove for list, always same index
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, isSingleItem: true, oldItem: item, oldStartingIndex: index)); //remove for list, always same index
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
index++; // not matched, skip index
|
ev2?.Invoke(RejectedViewChangedAction.Remove, index, -1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, (T value, TView view) value, int index, int oldIndex)
|
internal static void InvokeOnMove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, (T value, TView view) value, int index, int oldIndex)
|
||||||
{
|
{
|
||||||
InvokeOnMove(collection, ref filteredCount, ev, value.value, value.view, index, oldIndex);
|
InvokeOnMove(collection, ref filteredCount, ev, ev2, value.value, value.view, index, oldIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InvokeOnMove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, T value, TView view, int index, int oldIndex)
|
internal static void InvokeOnMove<T, TView>(this ISynchronizedView<T, TView> collection, ref int filteredCount, NotifyViewChangedEventHandler<T, TView>? ev, Action<RejectedViewChangedAction, int, int>? ev2, T value, TView view, int index, int oldIndex)
|
||||||
{
|
|
||||||
if (ev != null)
|
|
||||||
{
|
{
|
||||||
// move does not changes filtered-count
|
// move does not changes filtered-count
|
||||||
var isMatch = collection.Filter.IsMatch(value);
|
var isMatch = collection.Filter.IsMatch(value);
|
||||||
if (isMatch)
|
if (isMatch)
|
||||||
{
|
{
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Move, true, newItem: (value, view), newStartingIndex: index, oldStartingIndex: oldIndex));
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Move, true, newItem: (value, view), newStartingIndex: index, oldStartingIndex: oldIndex));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev2?.Invoke(RejectedViewChangedAction.Move, index, oldIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,29 +212,19 @@ namespace ObservableCollections
|
|||||||
|
|
||||||
if (bothMatched)
|
if (bothMatched)
|
||||||
{
|
{
|
||||||
if (ev != null)
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Replace, true, newItem: (value, view), oldItem: (oldValue, oldView), newStartingIndex: index, oldStartingIndex: oldIndex >= 0 ? oldIndex : index));
|
||||||
{
|
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Replace, true, newItem: (value, view), oldItem: (oldValue, oldView), newStartingIndex: index, oldStartingIndex: oldIndex >= 0 ? oldIndex : index));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (oldMatched)
|
else if (oldMatched)
|
||||||
{
|
{
|
||||||
// only-old is remove
|
// only-old is remove
|
||||||
filteredCount--;
|
filteredCount--;
|
||||||
if (ev != null)
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, true, oldItem: (value, view), oldStartingIndex: oldIndex));
|
||||||
{
|
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Remove, true, oldItem: (value, view), oldStartingIndex: oldIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (newMatched)
|
else if (newMatched)
|
||||||
{
|
{
|
||||||
// only-new is add
|
// only-new is add
|
||||||
filteredCount++;
|
filteredCount++;
|
||||||
if (ev != null)
|
ev?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, true, newItem: (value, view), newStartingIndex: index));
|
||||||
{
|
|
||||||
ev.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Add, true, newItem: (value, view), newStartingIndex: index));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ internal class FiltableSynchronizedViewList<T, TView> : ISynchronizedViewList<TV
|
|||||||
{
|
{
|
||||||
listView = new AlternateIndexList<TView>(IterateFilteredIndexedViewsOfParent());
|
listView = new AlternateIndexList<TView>(IterateFilteredIndexedViewsOfParent());
|
||||||
parent.ViewChanged += Parent_ViewChanged;
|
parent.ViewChanged += Parent_ViewChanged;
|
||||||
|
parent.RejectedViewChanged += Parent_RejectedViewChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +154,27 @@ internal class FiltableSynchronizedViewList<T, TView> : ISynchronizedViewList<TV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Parent_RejectedViewChanged(RejectedViewChangedAction arg1, int index, int oldIndex)
|
||||||
|
{
|
||||||
|
lock (gate)
|
||||||
|
{
|
||||||
|
switch (arg1)
|
||||||
|
{
|
||||||
|
case RejectedViewChangedAction.Add:
|
||||||
|
listView.UpdateAlternateIndex(index, 1);
|
||||||
|
break;
|
||||||
|
case RejectedViewChangedAction.Remove:
|
||||||
|
listView.UpdateAlternateIndex(index, -1);
|
||||||
|
break;
|
||||||
|
case RejectedViewChangedAction.Move:
|
||||||
|
listView.TryReplaceAlternateIndex(oldIndex, index);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> args)
|
protected virtual void OnCollectionChanged(in SynchronizedViewChangedEventArgs<T, TView> args)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -198,6 +220,7 @@ internal class FiltableSynchronizedViewList<T, TView> : ISynchronizedViewList<TV
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
parent.ViewChanged -= Parent_ViewChanged;
|
parent.ViewChanged -= Parent_ViewChanged;
|
||||||
|
parent.RejectedViewChanged -= Parent_RejectedViewChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user