From 68618fda10faef131724223cf85309b15d921a31 Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 23 Aug 2024 17:09:32 +0900 Subject: [PATCH] more interface change --- .../IObservableCollection.cs | 12 +++--- .../ISynchronizedViewFilter.cs | 38 ++++++++++++------- ...NotifyCollectionChangedSynchronizedView.cs | 19 +++++++--- .../ObservableList.Views.cs | 34 ++++++++--------- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/ObservableCollections/IObservableCollection.cs b/src/ObservableCollections/IObservableCollection.cs index 108fab8..7ce908e 100644 --- a/src/ObservableCollections/IObservableCollection.cs +++ b/src/ObservableCollections/IObservableCollection.cs @@ -32,19 +32,17 @@ namespace ObservableCollections ISortableSynchronizedView CreateSortableView(Func transform); } - public interface ISynchronizedView : IReadOnlyCollection<(T Value, TView View)>, IDisposable + public interface ISynchronizedView : IReadOnlyCollection, IDisposable { object SyncRoot { get; } - ISynchronizedViewFilter CurrentFilter { get; } + ISynchronizedViewFilter Filter { get; } + IEnumerable<(T Value, TView View)> Unfiltered { get; } - // TODO: add event Action>? ViewChanged; - // TODO: remove - // event NotifyCollectionChangedEventHandler? RoutingCollectionChanged; event Action? CollectionStateChanged; - void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForInitialElements = false); - void ResetFilter(Action? resetAction); + void AttachFilter(ISynchronizedViewFilter filter); + void ResetFilter(); INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(); INotifyCollectionChangedSynchronizedView ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher); } diff --git a/src/ObservableCollections/ISynchronizedViewFilter.cs b/src/ObservableCollections/ISynchronizedViewFilter.cs index 0a080a9..85c0b11 100644 --- a/src/ObservableCollections/ISynchronizedViewFilter.cs +++ b/src/ObservableCollections/ISynchronizedViewFilter.cs @@ -4,7 +4,7 @@ using System.Collections.Specialized; namespace ObservableCollections { public readonly struct SynchronizedViewChangedEventArgs( - NotifyCollectionChangedAction action, + NotifyViewChangedAction action, T newValue = default!, T oldValue = default!, TView newView = default!, @@ -12,7 +12,7 @@ namespace ObservableCollections int newViewIndex = -1, int oldViewIndex = -1) { - public readonly NotifyCollectionChangedAction Action = action; + public readonly NotifyViewChangedAction Action = action; public readonly T NewValue = newValue; public readonly T OldValue = oldValue; public readonly TView NewView = newView; @@ -21,6 +21,16 @@ namespace ObservableCollections public readonly int OldViewIndex = oldViewIndex; } + public enum NotifyViewChangedAction + { + Add = 0, + Remove = 1, + Replace = 2, + Move = 3, + Reset = 4, + FilterReset = 5, + } + public interface ISynchronizedViewFilter { bool IsMatch(T value); @@ -57,13 +67,13 @@ namespace ObservableCollections internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, int index) { - var isMatch = collection.CurrentFilter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value); if (isMatch) { filteredCount++; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); } } } @@ -75,13 +85,13 @@ namespace ObservableCollections internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, int oldIndex) { - var isMatch = collection.CurrentFilter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value); if (isMatch) { filteredCount--; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); } } } @@ -96,10 +106,10 @@ namespace ObservableCollections if (ev != null) { // move does not changes filtered-count - var isMatch = collection.CurrentFilter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value); if (isMatch) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Move, newValue: value, newView: view, newViewIndex: index, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Move, newValue: value, newView: view, newViewIndex: index, oldViewIndex: oldIndex)); } } } @@ -111,15 +121,15 @@ namespace ObservableCollections internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, Action>? ev, T value, TView view, T oldValue, TView oldView, int index, int oldIndex = -1) { - var oldMatched = collection.CurrentFilter.IsMatch(oldValue); - var newMatched = collection.CurrentFilter.IsMatch(value); + var oldMatched = collection.Filter.IsMatch(oldValue); + var newMatched = collection.Filter.IsMatch(value); var bothMatched = oldMatched && newMatched; if (bothMatched) { if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Replace, newValue: value, newView: view, oldValue: oldValue, oldView: oldView, newViewIndex: index, oldViewIndex: oldIndex >= 0 ? oldIndex : index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Replace, newValue: value, newView: view, oldValue: oldValue, oldView: oldView, newViewIndex: index, oldViewIndex: oldIndex >= 0 ? oldIndex : index)); } } else if (oldMatched) @@ -128,7 +138,7 @@ namespace ObservableCollections filteredCount--; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Remove, oldValue: value, oldView: view, oldViewIndex: oldIndex)); } } @@ -138,7 +148,7 @@ namespace ObservableCollections filteredCount++; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Add, newValue: value, newView: view, newViewIndex: index)); } } } @@ -148,7 +158,7 @@ namespace ObservableCollections filteredCount = 0; if (ev != null) { - ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset)); + ev.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.Reset)); } } } diff --git a/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs b/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs index 97a5251..0a3ed01 100644 --- a/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs +++ b/src/ObservableCollections/Internal/NotifyCollectionChangedSynchronizedView.cs @@ -26,7 +26,7 @@ namespace ObservableCollections.Internal // TODO: invoke in ICollectionEventDispatcher? switch (e.Action) { - case NotifyCollectionChangedAction.Add: // Add or Insert + case NotifyViewChangedAction.Add: // Add or Insert if (e.NewViewIndex == -1) { listView.Add(e.NewView); @@ -36,7 +36,7 @@ namespace ObservableCollections.Internal listView.Insert(e.NewViewIndex, e.NewView); } break; - case NotifyCollectionChangedAction.Remove: // Remove + case NotifyViewChangedAction.Remove: // Remove if (e.OldViewIndex == -1) // can't gurantee correct remove if index is not provided { listView.Remove(e.OldView); @@ -46,7 +46,7 @@ namespace ObservableCollections.Internal listView.RemoveAt(e.OldViewIndex); } break; - case NotifyCollectionChangedAction.Replace: // Indexer + case NotifyViewChangedAction.Replace: // Indexer if (e.NewViewIndex == -1) { var index = listView.IndexOf(e.OldView); @@ -58,7 +58,7 @@ namespace ObservableCollections.Internal } break; - case NotifyCollectionChangedAction.Move: //Remove and Insert + case NotifyViewChangedAction.Move: //Remove and Insert if (e.NewViewIndex == -1) { // do nothing @@ -69,9 +69,16 @@ namespace ObservableCollections.Internal listView.Insert(e.NewViewIndex, e.NewView); } break; - case NotifyCollectionChangedAction.Reset: // Clear + case NotifyViewChangedAction.Reset: // Clear listView.Clear(); break; + case NotifyViewChangedAction.FilterReset: + listView.Clear(); + foreach (var item in parent) + { + listView.Add(item.View); + } + break; default: break; } @@ -116,7 +123,7 @@ namespace ObservableCollections.Internal { this.parent = parent; this.eventDispatcher = eventDispatcher ?? DirectCollectionEventDispatcher.Instance; - currentFilter = parent.CurrentFilter; + currentFilter = parent.Filter; parent.AttachFilter(this); } diff --git a/src/ObservableCollections/ObservableList.Views.cs b/src/ObservableCollections/ObservableList.Views.cs index 8ec2beb..03a4ccd 100644 --- a/src/ObservableCollections/ObservableList.Views.cs +++ b/src/ObservableCollections/ObservableList.Views.cs @@ -16,7 +16,7 @@ namespace ObservableCollections internal sealed class View : ISynchronizedView { - public ISynchronizedViewFilter CurrentFilter + public ISynchronizedViewFilter Filter { get { @@ -63,38 +63,38 @@ namespace ObservableCollections } } - public void AttachFilter(ISynchronizedViewFilter filter, bool invokeAddEventForCurrentElements = false) + public void AttachFilter(ISynchronizedViewFilter filter) { + if (filter.IsNullFilter()) + { + ResetFilter(); + return; + } + lock (SyncRoot) { this.filter = filter; + + this.filteredCount = 0; for (var i = 0; i < list.Count; i++) { - var (value, view) = list[i]; - if (invokeAddEventForCurrentElements) + if (filter.IsMatch(list[i].Item1)) { - filter.InvokeOnAdd(value, view, i); - } - else - { - filter.InvokeOnAttach(value, view); + filteredCount++; } } + + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); } } - public void ResetFilter(Action? resetAction) + public void ResetFilter() { lock (SyncRoot) { this.filter = SynchronizedViewFilter.Null; - if (resetAction != null) - { - foreach (var (item, view) in list) - { - resetAction(item, view); - } - } + this.filteredCount = list.Count; + ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyViewChangedAction.FilterReset)); } }