From a8065bf6e60a4a3cc9b4191ebb92a44f26ccdcaa Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Mon, 15 Jul 2024 23:07:23 +0800 Subject: [PATCH] refine AdvancedCollectionView --- .../Core/Database/AdvancedDbCollectionView.cs | 8 +- .../Core/ExceptionService/HutaoException.cs | 9 ++ .../UI/Xaml/Data/AdvancedCollectionView.cs | 133 +++++++++--------- .../UI/Xaml/Data/IAdvancedCollectionView.cs | 4 - .../UI/Xaml/View/Dialog/UIGFImportDialog.xaml | 2 +- 5 files changed, 81 insertions(+), 75 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs index 6f57bdc5..44bf702e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Database/AdvancedDbCollectionView.cs @@ -30,14 +30,14 @@ internal sealed class AdvancedDbCollectionView : AdvancedCollectionView protected override void OnCurrentChangedOverride() { - if (serviceProvider is null || !savingToDatabase) + if (!savingToDatabase) { return; } TEntity? currentItem = CurrentItem; - foreach (TEntity item in Source) + foreach (TEntity item in SourceCollection) { item.IsSelected = ReferenceEquals(item, currentItem); } @@ -97,14 +97,14 @@ internal sealed class AdvancedDbCollectionView : Advance protected override void OnCurrentChangedOverride() { - if (serviceProvider is null || !savingToDatabase) + if (!savingToDatabase) { return; } TEntityAccess? currentItem = CurrentItem; - foreach (TEntityAccess item in Source) + foreach (TEntityAccess item in SourceCollection) { item.Entity.IsSelected = ReferenceEquals(item, currentItem); } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs index cec74ad6..0f42bc8d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs @@ -73,6 +73,15 @@ internal sealed class HutaoException : Exception throw new NotSupportedException(message, innerException); } + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotSupportedIf(bool condition, string? message = default, Exception? innerException = default) + { + if (condition) + { + throw new NotSupportedException(message, innerException); + } + } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static OperationCanceledException OperationCanceled(string message, Exception? innerException = default) diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs index 60104ce7..99612fef 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/AdvancedCollectionView.cs @@ -4,6 +4,7 @@ using CommunityToolkit.WinUI.Collections; using CommunityToolkit.WinUI.Helpers; using Microsoft.UI.Xaml.Data; +using Snap.Hutao.Core.ExceptionService; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Specialized; @@ -21,7 +22,6 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr private readonly bool created; private readonly List view; private readonly ObservableCollection sortDescriptions; - //private readonly HashSet observedFilterProperties = []; private IList source; private Predicate? filter; @@ -56,7 +56,8 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr get => view.Count; } - public bool IsReadOnly { get => source is null || source is not INotifyCollectionChanged || source.IsReadOnly; } + [Obsolete("IsReadOnly is not supported")] + public bool IsReadOnly { get => source is null; } public IObservableVector CollectionGroups { @@ -77,8 +78,6 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr public bool IsCurrentBeforeFirst { get => CurrentPosition < 0; } - public bool CanFilter { get => true; } - public Predicate? Filter { get => filter; @@ -94,11 +93,6 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr } } - public bool CanSort - { - get => true; - } - public ObservableCollection SortDescriptions { get => sortDescriptions; } public IList SourceCollection { get => source; } @@ -306,40 +300,38 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr ArgumentNullException.ThrowIfNull(item); T typedItem = (T)item; - if ((filter?.Invoke(typedItem) ?? true) && SortDescriptions.Any(sd => sd.PropertyName == e.PropertyName)) + if (!(filter?.Invoke(typedItem) ?? true) || !SortDescriptions.Any(sd => sd.PropertyName == e.PropertyName)) { - int oldIndex = view.IndexOf(typedItem); - - // Check if item is in view: - if (oldIndex < 0) - { - return; - } - - view.RemoveAt(oldIndex); - int targetIndex = view.BinarySearch(typedItem, this); - if (targetIndex < 0) - { - targetIndex = ~targetIndex; - } - - // Only trigger expensive UI updates if the index really changed: - if (targetIndex != oldIndex) - { - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemRemoved, oldIndex, typedItem)); - - view.Insert(targetIndex, typedItem); - - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemInserted, targetIndex, typedItem)); - } - else - { - view.Insert(targetIndex, typedItem); - } + return; } - else if (string.IsNullOrEmpty(e.PropertyName)) + + int oldIndex = view.IndexOf(typedItem); + + // Check if item is in view + if (oldIndex < 0) { - HandleSourceChanged(); + return; + } + + view.RemoveAt(oldIndex); + int targetIndex = view.BinarySearch(typedItem, comparer: this); + if (targetIndex < 0) + { + targetIndex = ~targetIndex; + } + + // Only trigger expensive UI updates if the index really changed + if (targetIndex != oldIndex) + { + OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemRemoved, oldIndex, typedItem)); + + view.Insert(targetIndex, typedItem); + + OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemInserted, targetIndex, typedItem)); + } + else + { + view.Insert(targetIndex, typedItem); } } @@ -464,47 +456,53 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr case NotifyCollectionChangedAction.Add: ArgumentNullException.ThrowIfNull(e.NewItems); AttachPropertyChangedHandler(e.NewItems); - if (deferCounter <= 0) + if (deferCounter > 0) { - if (e.NewItems?.Count == 1) - { - object? newItem = e.NewItems[0]; - ArgumentNullException.ThrowIfNull(newItem); - HandleSourceItemAdded(e.NewStartingIndex, (T)newItem); - } - else - { - HandleSourceChanged(); - } + break; + } + + if (e.NewItems?.Count is 1) + { + object? newItem = e.NewItems[0]; + ArgumentNullException.ThrowIfNull(newItem); + HandleSourceItemAdded(e.NewStartingIndex, (T)newItem); + } + else + { + HandleSourceChanged(); } break; case NotifyCollectionChangedAction.Remove: ArgumentNullException.ThrowIfNull(e.OldItems); DetachPropertyChangedHandler(e.OldItems); - if (deferCounter <= 0) + if (deferCounter > 0) { - if (e.OldItems?.Count == 1) - { - object? oldItem = e.OldItems[0]; - ArgumentNullException.ThrowIfNull(oldItem); - HandleSourceItemRemoved(e.OldStartingIndex, (T)oldItem); - } - else - { - HandleSourceChanged(); - } + break; + } + + if (e.OldItems?.Count == 1) + { + object? oldItem = e.OldItems[0]; + ArgumentNullException.ThrowIfNull(oldItem); + HandleSourceItemRemoved(e.OldStartingIndex, (T)oldItem); + } + else + { + HandleSourceChanged(); } break; case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Reset: - if (deferCounter <= 0) + if (deferCounter > 0) { - HandleSourceChanged(); + break; } + HandleSourceChanged(); + break; } } @@ -516,7 +514,7 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr return false; } - int newViewIndex = view.Count; + int newViewIndex = newStartingIndex; if (sortDescriptions.Count > 0) { @@ -599,7 +597,10 @@ internal class AdvancedCollectionView : IAdvancedCollectionView, INotifyPr view.RemoveAt(itemIndex); if (itemIndex <= CurrentPosition) { - if (itemIndex == CurrentPosition--) + CurrentPosition--; + + // Removed item is last item + if (view.Count == itemIndex) { OnCurrentChanged(); } diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/IAdvancedCollectionView.cs b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/IAdvancedCollectionView.cs index 2841cf0f..8f9c6d77 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/IAdvancedCollectionView.cs +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/Data/IAdvancedCollectionView.cs @@ -12,10 +12,6 @@ namespace Snap.Hutao.UI.Xaml.Data; internal interface IAdvancedCollectionView : ICollectionView, IEnumerable where T : class { - bool CanFilter { get; } - - bool CanSort { get; } - object? ICollectionView.CurrentItem { get => CurrentItem; diff --git a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/UIGFImportDialog.xaml b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/UIGFImportDialog.xaml index 1e83841d..16eba87b 100644 --- a/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/UIGFImportDialog.xaml +++ b/src/Snap.Hutao/Snap.Hutao/UI/Xaml/View/Dialog/UIGFImportDialog.xaml @@ -77,4 +77,4 @@ - + \ No newline at end of file