From 73a452f8550082a2ecefdffdeec7594cb4dc6b7c Mon Sep 17 00:00:00 2001 From: chinboy Date: Wed, 29 Oct 2025 11:32:59 +0800 Subject: [PATCH] Refactor ListBox Data --- .../Data/IListBoxCollectionView.cs} | 11 +- .../ListBox/Data/ListBoxCollectionView.cs | 279 ++++++++++++++++++ .../Data/ListBoxCollectionViewGroup.cs} | 8 +- .../ListBoxCollectionViewGroupInternal.cs} | 62 ++-- .../Data/ListBoxCollectionViewGroupRoot.cs} | 56 ++-- .../Data/ListBoxDefaultFilter.cs} | 10 +- .../Data/ListBoxFilterDescription.cs} | 4 +- .../Data/ListBoxGroupDescription.cs} | 4 +- .../Data/ListBoxPathGroupDescription.cs} | 4 +- .../Data/ListBoxSortDescription.cs} | 36 +-- 10 files changed, 381 insertions(+), 93 deletions(-) rename src/AtomUI.Controls/{Select/Data/ISelectOptionCollectionView.cs => ListBox/Data/IListBoxCollectionView.cs} (55%) create mode 100644 src/AtomUI.Controls/ListBox/Data/ListBoxCollectionView.cs rename src/AtomUI.Controls/{Select/Data/SelectCollectionViewGroup.cs => ListBox/Data/ListBoxCollectionViewGroup.cs} (79%) rename src/AtomUI.Controls/{Select/Data/SelectCollectionViewGroupInternal.cs => ListBox/Data/ListBoxCollectionViewGroupInternal.cs} (89%) rename src/AtomUI.Controls/{Select/Data/SelectCollectionViewGroupRoot.cs => ListBox/Data/ListBoxCollectionViewGroupRoot.cs} (87%) rename src/AtomUI.Controls/{Select/Data/SelectDefaultFilter.cs => ListBox/Data/ListBoxDefaultFilter.cs} (66%) rename src/AtomUI.Controls/{Select/Data/SelectFilterDescription.cs => ListBox/Data/ListBoxFilterDescription.cs} (94%) rename src/AtomUI.Controls/{Select/Data/SelectGroupDescription.cs => ListBox/Data/ListBoxGroupDescription.cs} (90%) rename src/AtomUI.Controls/{Select/Data/SelectPathGroupDescription.cs => ListBox/Data/ListBoxPathGroupDescription.cs} (94%) rename src/AtomUI.Controls/{Select/Data/SelectSortDescription.cs => ListBox/Data/ListBoxSortDescription.cs} (86%) diff --git a/src/AtomUI.Controls/Select/Data/ISelectOptionCollectionView.cs b/src/AtomUI.Controls/ListBox/Data/IListBoxCollectionView.cs similarity index 55% rename from src/AtomUI.Controls/Select/Data/ISelectOptionCollectionView.cs rename to src/AtomUI.Controls/ListBox/Data/IListBoxCollectionView.cs index be41077a7..1dfbe2376 100644 --- a/src/AtomUI.Controls/Select/Data/ISelectOptionCollectionView.cs +++ b/src/AtomUI.Controls/ListBox/Data/IListBoxCollectionView.cs @@ -1,15 +1,24 @@ using System.Collections; using System.Collections.Specialized; using System.Globalization; +using Avalonia.Collections; namespace AtomUI.Controls.Data; -internal interface ISelectOptionCollectionView: IEnumerable, INotifyCollectionChanged +internal interface IListBoxCollectionView: IEnumerable, INotifyCollectionChanged { CultureInfo Culture { get; set; } bool Contains(object item); IEnumerable SourceCollection { get; } Func? Filter { get; set; } + bool CanFilter { get; } + bool CanSort { get; } + bool CanGroup { get; } + bool IsGrouping { get; } + int GroupingDepth { get; } + string GetGroupingPropertyNameAtDepth(int level); + IAvaloniaReadOnlyList? Groups { get; } + SelectSortDescriptionCollection? SortDescriptions { get; } SelectFilterDescriptionCollection? FilterDescriptions { get; } bool IsEmpty { get; } void Refresh(); diff --git a/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionView.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionView.cs new file mode 100644 index 000000000..ea7d6ae5d --- /dev/null +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionView.cs @@ -0,0 +1,279 @@ +// using System.Collections; +// using System.ComponentModel; +// using System.Globalization; +// using System.Reflection; +// using AtomUI.Controls.Data; +// +// namespace AtomUI.Controls; +// +// internal class SelectOptionCollectionView : IListBoxCollectionView, IList, INotifyPropertyChanged +// { +// #region 公共属性定义 +// +// +// +// #endregion +// +// #region 公共事件定义 +// +// +// +// #endregion +// +// #region 内部属性定义 +// +// +// +// #endregion +// +// /// +// /// CultureInfo used in this DataGridCollectionView +// /// +// private CultureInfo _culture; +// +// /// +// /// Private accessor for the Monitor we use to prevent recursion +// /// +// private SimpleMonitor _currentChangedMonitor = new SimpleMonitor(); +// +// /// +// /// The number of requests to defer Refresh() +// /// +// private int _deferLevel; +// +// /// +// /// Private accessor for the Filter +// /// +// private Func? _filter; +// +// /// +// /// Private accessor for the CollectionViewFlags +// /// +// private CollectionViewFlags _flags = CollectionViewFlags.ShouldProcessCollectionChanged; +// +// /// +// /// Private accessor for the Grouping data +// /// +// private ListBoxCollectionViewGroupRoot _group; +// +// /// +// /// Private accessor for the InternalList +// /// +// private IList _internalList; +// +// /// +// /// Keeps track of whether groups have been applied to the +// /// collection already or not. Note that this can still be set +// /// to false even though we specify a GroupDescription, as the +// /// collection may not have gone through the PrepareGroups function. +// /// +// private bool _isGrouping; +// +// /// +// /// Private accessor for indicating whether we want to point to the temporary grouping data for calculations +// /// +// private bool _isUsingTemporaryGroup; +// +// /// +// /// ConstructorInfo obtained from reflection for generating new items +// /// +// private ConstructorInfo? _itemConstructor; +// +// /// +// /// Whether we have the correct ConstructorInfo information for the ItemConstructor +// /// +// private bool _itemConstructorIsValid; +// +// /// +// /// The new item we are getting ready to add to the collection +// /// +// private object? _newItem; +// +// /// +// /// Whether the source needs to poll for changes +// /// (if it did not implement INotifyCollectionChanged) +// /// +// private bool _pollForChanges; +// +// /// +// /// Private accessor for the SortDescriptions +// /// +// private SelectSortDescriptionCollection? _sortDescriptions; +// +// /// +// /// Private accessor for the FilterDescriptions +// /// +// private SelectFilterDescriptionCollection? _filterDescriptions; +// +// [Flags] +// private enum CollectionViewFlags +// { +// /// +// /// Whether the list of items (after applying the sort and filters, if any) +// /// is already in the correct order for grouping. +// /// +// IsDataInGroupOrder = 0x01, +// +// /// +// /// Whether the source collection is already sorted according to the SortDescriptions collection +// /// +// IsDataSorted = 0x02, +// +// /// +// /// Whether we should process the collection changed event +// /// +// ShouldProcessCollectionChanged = 0x04, +// +// /// +// /// Whether we need to refresh +// /// +// NeedsRefresh = 0x10, +// +// /// +// /// Whether we cache the IsEmpty value +// /// +// CachedIsEmpty = 0x20, +// +// /// +// /// Indicates whether a page index change is in process or not +// /// +// IsPageChanging = 0x40, +// +// /// +// /// Whether we need to move to another page after EndDefer +// /// +// IsMoveToPageDeferred = 0x100, +// +// /// +// /// Whether we need to update the PageSize after EndDefer +// /// +// IsUpdatePageSizeDeferred = 0x200 +// } +// +// /// +// /// A simple monitor class to help prevent re-entrant calls +// /// +// private class SimpleMonitor : IDisposable +// { +// /// +// /// Whether the monitor is entered +// /// +// private bool _entered; +// +// /// +// /// Gets a value indicating whether we have been entered or not +// /// +// public bool Busy => _entered; +// +// /// +// /// Sets a value indicating that we have been entered +// /// +// /// Boolean value indicating whether we were already entered +// public bool Enter() +// { +// if (_entered) +// { +// return false; +// } +// +// _entered = true; +// return true; +// } +// +// /// +// /// Cleanup method called when done using this class +// /// +// public void Dispose() +// { +// _entered = false; +// GC.SuppressFinalize(this); +// } +// } +// +// private class DeferHelper : IDisposable +// { +// /// +// /// Private reference to the CollectionView that created this DeferHelper +// /// +// private SelectOptionCollectionView? _collectionView; +// +// /// +// /// Initializes a new instance of the DeferHelper class +// /// +// /// CollectionView that created this DeferHelper +// public DeferHelper(SelectOptionCollectionView? collectionView) +// { +// _collectionView = collectionView; +// } +// +// /// +// /// Cleanup method called when done using this class +// /// +// public void Dispose() +// { +// if (_collectionView != null) +// { +// _collectionView.EndDefer(); +// _collectionView = null; +// } +// +// GC.SuppressFinalize(this); +// } +// } +// +// /// +// /// Creates a comparer class that takes in a CultureInfo as a parameter, +// /// which it will use when comparing strings. +// /// +// private class CultureSensitiveComparer : IComparer +// { +// /// +// /// Private accessor for the CultureInfo of our comparer +// /// +// private CultureInfo _culture; +// +// /// +// /// Creates a comparer which will respect the CultureInfo +// /// that is passed in when comparing strings. +// /// +// /// The CultureInfo to use in string comparisons +// public CultureSensitiveComparer(CultureInfo? culture) +// { +// _culture = culture ?? CultureInfo.InvariantCulture; +// } +// +// /// +// /// Compares two objects and returns a value indicating whether one is less than, equal to or greater than the other. +// /// +// /// first item to compare +// /// second item to compare +// /// Negative number if x is less than y, zero if equal, and a positive number if x is greater than y +// /// +// /// Compares the 2 items using the specified CultureInfo for string and using the default object comparer for all other objects. +// /// +// public int Compare(object? x, object? y) +// { +// if (x == null) +// { +// if (y != null) +// { +// return -1; +// } +// +// return 0; +// } +// +// if (y == null) +// { +// return 1; +// } +// +// // at this point x and y are not null +// if (x is string xString && y is string yString) +// { +// return _culture.CompareInfo.Compare(xString, yString); +// } +// return Comparer.Default.Compare(x, y); +// } +// } +// } \ No newline at end of file diff --git a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroup.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroup.cs similarity index 79% rename from src/AtomUI.Controls/Select/Data/SelectCollectionViewGroup.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroup.cs index d8bde8721..d0db6b90d 100644 --- a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroup.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroup.cs @@ -3,7 +3,7 @@ using Avalonia.Collections; namespace AtomUI.Controls.Data; -public abstract class SelectCollectionViewGroup : INotifyPropertyChanged +public abstract class ListBoxCollectionViewGroup : INotifyPropertyChanged { private int _itemCount; public object Key { get; } @@ -21,10 +21,10 @@ public abstract class SelectCollectionViewGroup : INotifyPropertyChanged } } - internal abstract SelectCollectionViewGroupInternal? Parent { get; } - internal abstract SelectGroupDescription? GroupBy { get; set; } + internal abstract ListBoxCollectionViewGroupInternal? Parent { get; } + internal abstract ListBoxGroupDescription? GroupBy { get; set; } - protected SelectCollectionViewGroup(object key) + protected ListBoxCollectionViewGroup(object key) { Key = key; ProtectedItems = new AvaloniaList(); diff --git a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupInternal.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupInternal.cs similarity index 89% rename from src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupInternal.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupInternal.cs index 532baf5c9..57bd0c7b8 100644 --- a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupInternal.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupInternal.cs @@ -5,24 +5,24 @@ using Avalonia; namespace AtomUI.Controls.Data; -internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup +internal class ListBoxCollectionViewGroupInternal : ListBoxCollectionViewGroup { /// /// GroupDescription used to define how to group the items /// - private SelectGroupDescription? _groupBy; + private ListBoxGroupDescription? _groupBy; /// - /// Parent group of this SelectCollectionViewGroupInternal + /// Parent group of this ListBoxCollectionViewGroupInternal /// - private readonly SelectCollectionViewGroupInternal? _parentGroup; + private readonly ListBoxCollectionViewGroupInternal? _parentGroup; /// /// Used for detecting stale enumerators /// private int _version; - public SelectCollectionViewGroupInternal(object key, SelectCollectionViewGroupInternal? parent) + public ListBoxCollectionViewGroupInternal(object key, ListBoxCollectionViewGroupInternal? parent) : base(key) { _parentGroup = parent; @@ -32,7 +32,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup internal int FullCount { get; set; } - internal override SelectGroupDescription? GroupBy + internal override ListBoxGroupDescription? GroupBy { get => _groupBy; set @@ -86,7 +86,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup // look for first item, child by child for (int k = 0, n = Items.Count; k < n; ++k) { - if (!(Items[k] is SelectCollectionViewGroupInternal subgroup)) + if (!(Items[k] is ListBoxCollectionViewGroupInternal subgroup)) { // child is an item - return it return Items[k]; @@ -111,7 +111,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup } } - internal override SelectCollectionViewGroupInternal? Parent => _parentGroup; + internal override ListBoxCollectionViewGroupInternal? Parent => _parentGroup; /// /// Adds the specified item to the collection @@ -166,7 +166,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup for (index = low; index < high; ++index) { - object seed1 = (ProtectedItems[index] is SelectCollectionViewGroupInternal subgroup) + object seed1 = (ProtectedItems[index] is ListBoxCollectionViewGroupInternal subgroup) ? subgroup.SeedItem : ProtectedItems[index]; if (seed1 == AvaloniaProperty.UnsetValue) @@ -230,7 +230,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup { for (int k = 0, n = Items.Count; k < n; ++k) { - if (Items[k] is SelectCollectionViewGroupInternal subgroup) + if (Items[k] is ListBoxCollectionViewGroupInternal subgroup) { // current item is a group - either drill in, or skip over if (index < subgroup.ItemCount) @@ -267,7 +267,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup int result = 0; // accumulate the number of predecessors at each level - for (SelectCollectionViewGroupInternal? group = this; + for (ListBoxCollectionViewGroupInternal? group = this; group != null; item = group, group = group.Parent, index = -1) { @@ -282,7 +282,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup } // accumulate leaf count - SelectCollectionViewGroupInternal? subgroup = group.Items[k] as SelectCollectionViewGroupInternal; + ListBoxCollectionViewGroupInternal? subgroup = group.Items[k] as ListBoxCollectionViewGroupInternal; result += subgroup?.ItemCount ?? 1; } } @@ -301,7 +301,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup int leaves = 0; // number of leaves we've passed over so far for (int k = 0, n = Items.Count; k < n; ++k) { - if (Items[k] is SelectCollectionViewGroupInternal subgroup) + if (Items[k] is ListBoxCollectionViewGroupInternal subgroup) { int subgroupIndex = subgroup.LeafIndexOf(item); if (subgroupIndex < 0) @@ -357,13 +357,13 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup /// Removes an empty group from the PagedCollectionView grouping /// /// Empty subgroup to remove - private static void RemoveEmptyGroup(SelectCollectionViewGroupInternal group) + private static void RemoveEmptyGroup(ListBoxCollectionViewGroupInternal group) { - SelectCollectionViewGroupInternal? parent = group.Parent; + ListBoxCollectionViewGroupInternal? parent = group.Parent; if (parent != null) { - SelectGroupDescription? groupBy = parent.GroupBy; + ListBoxGroupDescription? groupBy = parent.GroupBy; int index = parent.ProtectedItems.IndexOf(group); // remove the subgroup unless it is one of the explicit groups @@ -381,9 +381,9 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup /// Delta to change count by protected void ChangeCounts(object item, int delta) { - bool changeLeafCount = !(item is SelectCollectionViewGroup); + bool changeLeafCount = !(item is ListBoxCollectionViewGroup); - for (SelectCollectionViewGroupInternal? group = this; + for (ListBoxCollectionViewGroupInternal? group = this; group != null; group = group._parentGroup) { @@ -412,7 +412,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup private class LeafEnumerator : IEnumerator { private object? _current; // current item - private SelectCollectionViewGroupInternal? _group; // parent group + private ListBoxCollectionViewGroupInternal? _group; // parent group private int _index; // current index into Items private IEnumerator? _subEnum; // enumerator over current subgroup private int _version; // parent group's version at ctor @@ -421,7 +421,7 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup /// Initializes a new instance of the LeafEnumerator class. /// /// CollectionViewGroupInternal that uses the enumerator - public LeafEnumerator(SelectCollectionViewGroupInternal group) + public LeafEnumerator(ListBoxCollectionViewGroupInternal group) { _group = group; DoReset(); // don't call virtual Reset in ctor @@ -470,8 +470,8 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup return false; } - SelectCollectionViewGroupInternal? subgroup = - _group.Items[_index] as SelectCollectionViewGroupInternal; + ListBoxCollectionViewGroupInternal? subgroup = + _group.Items[_index] as ListBoxCollectionViewGroupInternal; if (subgroup == null) { // current item is a leaf - it's the new Current @@ -595,8 +595,8 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup // / // / This comparer is used to insert an item into a group in a position consistent - // / with a given SelectCollectionViewGroupRoot. We will only use this when dealing with - // / a temporary SelectCollectionViewGroupRoot that points to the correct grouping of the + // / with a given ListBoxCollectionViewGroupRoot. We will only use this when dealing with + // / a temporary ListBoxCollectionViewGroupRoot that points to the correct grouping of the // / entire collection, and we have paging that requires us to keep the paged group // / consistent with the order of items in the temporary group. // / @@ -604,10 +604,10 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup { /// /// Constructor for the CollectionViewGroupComparer that takes - /// in an SelectCollectionViewGroupRoot. + /// in an ListBoxCollectionViewGroupRoot. /// - /// SelectCollectionViewGroupRoot used to compare on - internal CollectionViewGroupComparer(SelectCollectionViewGroupRoot group) + /// ListBoxCollectionViewGroupRoot used to compare on + internal CollectionViewGroupComparer(ListBoxCollectionViewGroupRoot group) { _group = group; _index = 0; @@ -624,11 +624,11 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup /// /// Sets our group to a new instance of a - /// SelectCollectionViewGroupRoot being passed in + /// ListBoxCollectionViewGroupRoot being passed in /// and resets the index. /// - /// SelectCollectionViewGroupRoot used to compare on - internal void ResetGroup(SelectCollectionViewGroupRoot group) + /// ListBoxCollectionViewGroupRoot used to compare on + internal void ResetGroup(ListBoxCollectionViewGroupRoot group) { _group = group; _index = 0; @@ -669,6 +669,6 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup } private int _index; - private SelectCollectionViewGroupRoot _group; + private ListBoxCollectionViewGroupRoot _group; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupRoot.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupRoot.cs similarity index 87% rename from src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupRoot.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupRoot.cs index 51c4a537b..28390eac6 100644 --- a/src/AtomUI.Controls/Select/Data/SelectCollectionViewGroupRoot.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxCollectionViewGroupRoot.cs @@ -6,7 +6,7 @@ using Avalonia.Collections; namespace AtomUI.Controls.Data; -internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal, INotifyCollectionChanged +internal class ListBoxCollectionViewGroupRoot : ListBoxCollectionViewGroupInternal, INotifyCollectionChanged { /// /// String constant used for the Root Name @@ -21,12 +21,12 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// /// Private accessor for the top level GroupDescription /// - private static SelectGroupDescription? _topLevelGroupDescription; + private static ListBoxGroupDescription? _topLevelGroupDescription; /// /// Private accessor for an ObservableCollection containing group descriptions /// - private readonly AvaloniaList _groupBy = new (); + private readonly AvaloniaList _groupBy = new (); /// /// Indicates whether the list of items (after applying the sort and filters, if any) @@ -37,7 +37,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// /// Private accessor for the owning ICollectionView /// - private readonly ISelectOptionCollectionView _view; + private readonly IListBoxCollectionView _view; /// /// Raise this event when the (grouped) view changes @@ -50,11 +50,11 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal internal event EventHandler? GroupDescriptionChanged; /// - /// Initializes a new instance of the SelectCollectionViewGroupRoot class. + /// Initializes a new instance of the ListBoxCollectionViewGroupRoot class. /// /// CollectionView that contains this grouping /// True if items are already in correct order for grouping - internal SelectCollectionViewGroupRoot(ISelectOptionCollectionView view, bool isDataInGroupOrder) + internal ListBoxCollectionViewGroupRoot(IListBoxCollectionView view, bool isDataInGroupOrder) : base(RootName, null) { _view = view; @@ -64,7 +64,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// /// Gets the description of grouping, indexed by level. /// - public virtual AvaloniaList GroupDescriptions => _groupBy; + public virtual AvaloniaList GroupDescriptions => _groupBy; /// /// Gets or sets the current IComparer being used @@ -229,16 +229,16 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// The level of grouping. /// Name of subgroup to add to /// Whether we are currently loading - private void AddToSubgroup(object item, SelectCollectionViewGroupInternal group, int level, object key, + private void AddToSubgroup(object item, ListBoxCollectionViewGroupInternal group, int level, object key, bool loading) { - SelectCollectionViewGroupInternal? subgroup; + ListBoxCollectionViewGroupInternal? subgroup; int index = (_isDataInGroupOrder) ? group.LastIndex : 0; // find the desired subgroup for (int n = group.Items.Count; index < n; ++index) { - subgroup = group.Items[index] as SelectCollectionViewGroupInternal; + subgroup = group.Items[index] as ListBoxCollectionViewGroupInternal; if (subgroup == null) { continue; // skip children that are not groups @@ -253,7 +253,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal } // the item didn't match any subgroups. Create a new subgroup and add the item. - subgroup = new SelectCollectionViewGroupInternal(key, group); + subgroup = new ListBoxCollectionViewGroupInternal(key, group); InitializeGroup(subgroup, level + 1, item); if (loading) @@ -282,7 +282,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// Group to add item to /// The level of grouping /// Whether we are currently loading - private void AddToSubgroups(object item, SelectCollectionViewGroupInternal group, int level, bool loading) + private void AddToSubgroups(object item, ListBoxCollectionViewGroupInternal group, int level, bool loading) { object? key = GetGroupKey(item, group.GroupBy, level); @@ -322,7 +322,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal } } - public virtual Func? GroupBySelector { get; set; } + public virtual Func? GroupBySelector { get; set; } /// /// Returns the description of how to divide the given group into subgroups @@ -330,10 +330,10 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// CollectionViewGroup to get group description from /// The level of grouping /// GroupDescription of how to divide the given group - private SelectGroupDescription? GetGroupDescription(SelectCollectionViewGroup group, int level) + private ListBoxGroupDescription? GetGroupDescription(ListBoxCollectionViewGroup group, int level) { - SelectGroupDescription? result = null; - SelectCollectionViewGroup? targetGroup = group; + ListBoxGroupDescription? result = null; + ListBoxCollectionViewGroup? targetGroup = group; if (targetGroup == this) { targetGroup = null; @@ -359,7 +359,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// GroupDescription for the group /// The level of grouping /// Group names for the specified item - private object? GetGroupKey(object item, SelectGroupDescription? groupDescription, int level) + private object? GetGroupKey(object item, ListBoxGroupDescription? groupDescription, int level) { if (groupDescription != null) { @@ -374,10 +374,10 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// Group to initialize /// The level of grouping /// The seed item to compare with to see where to insert - private void InitializeGroup(SelectCollectionViewGroupInternal group, int level, object? seedItem) + private void InitializeGroup(ListBoxCollectionViewGroupInternal group, int level, object? seedItem) { // set the group description for dividing the group into subgroups - SelectGroupDescription? groupDescription = GetGroupDescription(group, level); + ListBoxGroupDescription? groupDescription = GetGroupDescription(group, level); group.GroupBy = groupDescription; // create subgroups for each of the explicit names @@ -386,7 +386,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal { for (int k = 0, n = keys.Count; k < n; ++k) { - SelectCollectionViewGroupInternal subgroup = new SelectCollectionViewGroupInternal(keys[k], group); + ListBoxCollectionViewGroupInternal subgroup = new ListBoxCollectionViewGroupInternal(keys[k], group); InitializeGroup(subgroup, level + 1, seedItem); group.Add(subgroup); } @@ -401,7 +401,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// Group to remove item from /// Item to remove /// True if item could not be removed - private bool RemoveFromGroupDirectly(SelectCollectionViewGroupInternal group, object item) + private bool RemoveFromGroupDirectly(ListBoxCollectionViewGroupInternal group, object item) { int leafIndex = group.Remove(item, true); if (leafIndex >= 0) @@ -421,15 +421,15 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// The level of grouping /// Name of item to remove /// Return true if the item was not in one of the subgroups it was supposed to be. - private bool RemoveFromSubgroup(object item, SelectCollectionViewGroupInternal group, int level, object key) + private bool RemoveFromSubgroup(object item, ListBoxCollectionViewGroupInternal group, int level, object key) { bool itemIsMissing = false; - SelectCollectionViewGroupInternal? subGroup; + ListBoxCollectionViewGroupInternal? subGroup; // find the desired subgroup for (int index = 0, n = group.Items.Count; index < n; ++index) { - subGroup = group.Items[index] as SelectCollectionViewGroupInternal; + subGroup = group.Items[index] as ListBoxCollectionViewGroupInternal; if (subGroup == null) { continue; // skip children that are not groups @@ -457,7 +457,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// Group to remove item from /// The level of grouping /// Return true if the item was not in one of the subgroups it was supposed to be. - private bool RemoveFromSubgroups(object item, SelectCollectionViewGroupInternal group, int level) + private bool RemoveFromSubgroups(object item, ListBoxCollectionViewGroupInternal group, int level) { bool itemIsMissing = false; object? key = GetGroupKey(item, group.GroupBy, level); @@ -502,7 +502,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// /// Group to remove item from /// Item to remove - private void RemoveItemFromSubgroupsByExhaustiveSearch(SelectCollectionViewGroupInternal group, object item) + private void RemoveItemFromSubgroupsByExhaustiveSearch(ListBoxCollectionViewGroupInternal group, object item) { // try to remove the item from the direct children // this function only returns true if it failed to remove from group directly @@ -513,7 +513,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal // (loop runs backwards in case an entire group is deleted) for (int k = group.Items.Count - 1; k >= 0; --k) { - if (group.Items[k] is SelectCollectionViewGroupInternal subgroup) + if (group.Items[k] is ListBoxCollectionViewGroupInternal subgroup) { RemoveItemFromSubgroupsByExhaustiveSearch(subgroup, item); } @@ -524,7 +524,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal /// /// TopLevelGroupDescription class /// - private class TopLevelGroupDescription : SelectGroupDescription + private class TopLevelGroupDescription : ListBoxGroupDescription { /// /// Initializes a new instance of the TopLevelGroupDescription class. diff --git a/src/AtomUI.Controls/Select/Data/SelectDefaultFilter.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxDefaultFilter.cs similarity index 66% rename from src/AtomUI.Controls/Select/Data/SelectDefaultFilter.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxDefaultFilter.cs index fa9364fba..0f16aef0f 100644 --- a/src/AtomUI.Controls/Select/Data/SelectDefaultFilter.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxDefaultFilter.cs @@ -1,12 +1,12 @@ namespace AtomUI.Controls.Data; -internal class SelectDefaultFilter +internal class ListBoxDefaultFilter { - private readonly WeakReference CollectionViewRef; + private readonly WeakReference CollectionViewRef; - public SelectDefaultFilter(ISelectOptionCollectionView collectionView) + public ListBoxDefaultFilter(IListBoxCollectionView collectionView) { - CollectionViewRef = new WeakReference(collectionView); + CollectionViewRef = new WeakReference(collectionView); } public bool Filter(object value) @@ -31,7 +31,7 @@ internal class SelectDefaultFilter return false; } - public static implicit operator Func(SelectDefaultFilter filter) + public static implicit operator Func(ListBoxDefaultFilter filter) { return filter.Filter; } diff --git a/src/AtomUI.Controls/Select/Data/SelectFilterDescription.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxFilterDescription.cs similarity index 94% rename from src/AtomUI.Controls/Select/Data/SelectFilterDescription.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxFilterDescription.cs index 86c1370a0..4af8853c0 100644 --- a/src/AtomUI.Controls/Select/Data/SelectFilterDescription.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxFilterDescription.cs @@ -4,7 +4,7 @@ using Avalonia.Collections; namespace AtomUI.Controls.Data; -public class SelectFilterDescription +public class ListBoxFilterDescription { public string? PropertyPath { get; set; } public bool HasPropertyPath => !string.IsNullOrEmpty(PropertyPath); @@ -79,4 +79,4 @@ public class SelectFilterDescription } } -public class SelectFilterDescriptionCollection : AvaloniaList {} \ No newline at end of file +public class SelectFilterDescriptionCollection : AvaloniaList {} \ No newline at end of file diff --git a/src/AtomUI.Controls/Select/Data/SelectGroupDescription.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxGroupDescription.cs similarity index 90% rename from src/AtomUI.Controls/Select/Data/SelectGroupDescription.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxGroupDescription.cs index f19bd1071..cb83f8924 100644 --- a/src/AtomUI.Controls/Select/Data/SelectGroupDescription.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxGroupDescription.cs @@ -4,11 +4,11 @@ using Avalonia.Collections; namespace AtomUI.Controls.Data; -public abstract class SelectGroupDescription : INotifyPropertyChanged +public abstract class ListBoxGroupDescription : INotifyPropertyChanged { public AvaloniaList GroupKeys { get; } - public SelectGroupDescription() + public ListBoxGroupDescription() { GroupKeys = new AvaloniaList(); GroupKeys.CollectionChanged += (sender, e) => OnPropertyChanged(new PropertyChangedEventArgs(nameof(GroupKeys))); diff --git a/src/AtomUI.Controls/Select/Data/SelectPathGroupDescription.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxPathGroupDescription.cs similarity index 94% rename from src/AtomUI.Controls/Select/Data/SelectPathGroupDescription.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxPathGroupDescription.cs index 9f44a4eac..09ea22a60 100644 --- a/src/AtomUI.Controls/Select/Data/SelectPathGroupDescription.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxPathGroupDescription.cs @@ -5,14 +5,14 @@ using Avalonia.Data.Converters; namespace AtomUI.Controls.Data; -public class SelectPathGroupDescription : SelectGroupDescription +public class ListBoxPathGroupDescription : ListBoxGroupDescription { private string _propertyPath; private Type? _propertyType; private IValueConverter? _valueConverter; private StringComparison _stringComparison = StringComparison.Ordinal; - public SelectPathGroupDescription(string propertyPath) + public ListBoxPathGroupDescription(string propertyPath) { _propertyPath = propertyPath; } diff --git a/src/AtomUI.Controls/Select/Data/SelectSortDescription.cs b/src/AtomUI.Controls/ListBox/Data/ListBoxSortDescription.cs similarity index 86% rename from src/AtomUI.Controls/Select/Data/SelectSortDescription.cs rename to src/AtomUI.Controls/ListBox/Data/ListBoxSortDescription.cs index 44afecf41..2cdd59c72 100644 --- a/src/AtomUI.Controls/Select/Data/SelectSortDescription.cs +++ b/src/AtomUI.Controls/ListBox/Data/ListBoxSortDescription.cs @@ -6,7 +6,7 @@ using Avalonia.Collections; namespace AtomUI.Controls.Data; -public abstract class SelectSortDescription +public abstract class ListBoxSortDescription { public virtual string? PropertyPath => null; @@ -26,7 +26,7 @@ public abstract class SelectSortDescription return seq.ThenBy(o => o, Comparer); } - public virtual SelectSortDescription SwitchSortDirection() + public virtual ListBoxSortDescription SwitchSortDirection() { return this; } @@ -47,19 +47,19 @@ public abstract class SelectSortDescription return propertyValue; } - public static SelectSortDescription FromPath(string propertyPath, ListSortDirection direction = ListSortDirection.Ascending, CultureInfo? culture = null) + public static ListBoxSortDescription FromPath(string propertyPath, ListSortDirection direction = ListSortDirection.Ascending, CultureInfo? culture = null) { - return new SelectPathSortDescription(propertyPath, direction, null, culture); + return new ListBoxPathSortDescription(propertyPath, direction, null, culture); } - public static SelectSortDescription FromPath(string propertyPath, ListSortDirection direction, IComparer comparer) + public static ListBoxSortDescription FromPath(string propertyPath, ListSortDirection direction, IComparer comparer) { - return new SelectPathSortDescription(propertyPath, direction, comparer, null); + return new ListBoxPathSortDescription(propertyPath, direction, comparer, null); } - public static SelectSortDescription FromComparer(IComparer comparer, ListSortDirection direction = ListSortDirection.Ascending) + public static ListBoxSortDescription FromComparer(IComparer comparer, ListSortDirection direction = ListSortDirection.Ascending) { - return new SelectComparerSortDescription(comparer, direction); + return new ListBoxComparerSortDescription(comparer, direction); } /// @@ -119,7 +119,7 @@ public abstract class SelectSortDescription } } - private class SelectPathSortDescription : SelectSortDescription + private class ListBoxPathSortDescription : ListBoxSortDescription { private readonly ListSortDirection _direction; private readonly string _propertyPath; @@ -153,7 +153,7 @@ public abstract class SelectSortDescription public override IComparer Comparer => _comparer.Value; public override ListSortDirection Direction => _direction; - public SelectPathSortDescription(string propertyPath, ListSortDirection direction, IComparer? internalComparer, + public ListBoxPathSortDescription(string propertyPath, ListSortDirection direction, IComparer? internalComparer, CultureInfo? culture) { _propertyPath = propertyPath; @@ -164,7 +164,7 @@ public abstract class SelectSortDescription _comparer = new Lazy>(() => Comparer.Create(Compare)); } - private SelectPathSortDescription(SelectPathSortDescription inner, ListSortDirection direction) + private ListBoxPathSortDescription(ListBoxPathSortDescription inner, ListSortDirection direction) { _propertyPath = inner._propertyPath; _direction = direction; @@ -297,17 +297,17 @@ public abstract class SelectSortDescription return seq.ThenBy(GetValue, InternalComparer); } - public override SelectSortDescription SwitchSortDirection() + public override ListBoxSortDescription SwitchSortDirection() { var newDirection = _direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; - return new SelectPathSortDescription(this, newDirection); + return new ListBoxPathSortDescription(this, newDirection); } } } -public class SelectComparerSortDescription : SelectSortDescription +public class ListBoxComparerSortDescription : ListBoxSortDescription { private readonly IComparer _innerComparer; private readonly ListSortDirection _direction; @@ -316,7 +316,7 @@ public class SelectComparerSortDescription : SelectSortDescription public IComparer SourceComparer => _innerComparer; public override IComparer Comparer => _comparer; public override ListSortDirection Direction => _direction; - public SelectComparerSortDescription(IComparer comparer, ListSortDirection direction) + public ListBoxComparerSortDescription(IComparer comparer, ListSortDirection direction) { _innerComparer = comparer; _direction = direction; @@ -335,11 +335,11 @@ public class SelectComparerSortDescription : SelectSortDescription return result; } - public override SelectSortDescription SwitchSortDirection() + public override ListBoxSortDescription SwitchSortDirection() { var newDirection = _direction == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; - return new SelectComparerSortDescription(_innerComparer, newDirection); + return new ListBoxComparerSortDescription(_innerComparer, newDirection); } } -public class SelectSortDescriptionCollection : AvaloniaList {} \ No newline at end of file +public class SelectSortDescriptionCollection : AvaloniaList {} \ No newline at end of file