mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-20 23:58:05 +08:00
Refactor ListBox Data
This commit is contained in:
+10
-1
@@ -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<object, bool>? Filter { get; set; }
|
||||
bool CanFilter { get; }
|
||||
bool CanSort { get; }
|
||||
bool CanGroup { get; }
|
||||
bool IsGrouping { get; }
|
||||
int GroupingDepth { get; }
|
||||
string GetGroupingPropertyNameAtDepth(int level);
|
||||
IAvaloniaReadOnlyList<object>? Groups { get; }
|
||||
SelectSortDescriptionCollection? SortDescriptions { get; }
|
||||
SelectFilterDescriptionCollection? FilterDescriptions { get; }
|
||||
bool IsEmpty { get; }
|
||||
void Refresh();
|
||||
@@ -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
|
||||
//
|
||||
// /// <summary>
|
||||
// /// CultureInfo used in this DataGridCollectionView
|
||||
// /// </summary>
|
||||
// private CultureInfo _culture;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the Monitor we use to prevent recursion
|
||||
// /// </summary>
|
||||
// private SimpleMonitor _currentChangedMonitor = new SimpleMonitor();
|
||||
//
|
||||
// /// <summary>
|
||||
// /// The number of requests to defer Refresh()
|
||||
// /// </summary>
|
||||
// private int _deferLevel;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the Filter
|
||||
// /// </summary>
|
||||
// private Func<object, bool>? _filter;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the CollectionViewFlags
|
||||
// /// </summary>
|
||||
// private CollectionViewFlags _flags = CollectionViewFlags.ShouldProcessCollectionChanged;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the Grouping data
|
||||
// /// </summary>
|
||||
// private ListBoxCollectionViewGroupRoot _group;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the InternalList
|
||||
// /// </summary>
|
||||
// private IList _internalList;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 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.
|
||||
// /// </summary>
|
||||
// private bool _isGrouping;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for indicating whether we want to point to the temporary grouping data for calculations
|
||||
// /// </summary>
|
||||
// private bool _isUsingTemporaryGroup;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// ConstructorInfo obtained from reflection for generating new items
|
||||
// /// </summary>
|
||||
// private ConstructorInfo? _itemConstructor;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we have the correct ConstructorInfo information for the ItemConstructor
|
||||
// /// </summary>
|
||||
// private bool _itemConstructorIsValid;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// The new item we are getting ready to add to the collection
|
||||
// /// </summary>
|
||||
// private object? _newItem;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether the source needs to poll for changes
|
||||
// /// (if it did not implement INotifyCollectionChanged)
|
||||
// /// </summary>
|
||||
// private bool _pollForChanges;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the SortDescriptions
|
||||
// /// </summary>
|
||||
// private SelectSortDescriptionCollection? _sortDescriptions;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Private accessor for the FilterDescriptions
|
||||
// /// </summary>
|
||||
// private SelectFilterDescriptionCollection? _filterDescriptions;
|
||||
//
|
||||
// [Flags]
|
||||
// private enum CollectionViewFlags
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Whether the list of items (after applying the sort and filters, if any)
|
||||
// /// is already in the correct order for grouping.
|
||||
// /// </summary>
|
||||
// IsDataInGroupOrder = 0x01,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether the source collection is already sorted according to the SortDescriptions collection
|
||||
// /// </summary>
|
||||
// IsDataSorted = 0x02,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we should process the collection changed event
|
||||
// /// </summary>
|
||||
// ShouldProcessCollectionChanged = 0x04,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we need to refresh
|
||||
// /// </summary>
|
||||
// NeedsRefresh = 0x10,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we cache the IsEmpty value
|
||||
// /// </summary>
|
||||
// CachedIsEmpty = 0x20,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Indicates whether a page index change is in process or not
|
||||
// /// </summary>
|
||||
// IsPageChanging = 0x40,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we need to move to another page after EndDefer
|
||||
// /// </summary>
|
||||
// IsMoveToPageDeferred = 0x100,
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Whether we need to update the PageSize after EndDefer
|
||||
// /// </summary>
|
||||
// IsUpdatePageSizeDeferred = 0x200
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// A simple monitor class to help prevent re-entrant calls
|
||||
// /// </summary>
|
||||
// private class SimpleMonitor : IDisposable
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Whether the monitor is entered
|
||||
// /// </summary>
|
||||
// private bool _entered;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Gets a value indicating whether we have been entered or not
|
||||
// /// </summary>
|
||||
// public bool Busy => _entered;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Sets a value indicating that we have been entered
|
||||
// /// </summary>
|
||||
// /// <returns>Boolean value indicating whether we were already entered</returns>
|
||||
// public bool Enter()
|
||||
// {
|
||||
// if (_entered)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// _entered = true;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Cleanup method called when done using this class
|
||||
// /// </summary>
|
||||
// public void Dispose()
|
||||
// {
|
||||
// _entered = false;
|
||||
// GC.SuppressFinalize(this);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private class DeferHelper : IDisposable
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Private reference to the CollectionView that created this DeferHelper
|
||||
// /// </summary>
|
||||
// private SelectOptionCollectionView? _collectionView;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Initializes a new instance of the DeferHelper class
|
||||
// /// </summary>
|
||||
// /// <param name="collectionView">CollectionView that created this DeferHelper</param>
|
||||
// public DeferHelper(SelectOptionCollectionView? collectionView)
|
||||
// {
|
||||
// _collectionView = collectionView;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Cleanup method called when done using this class
|
||||
// /// </summary>
|
||||
// public void Dispose()
|
||||
// {
|
||||
// if (_collectionView != null)
|
||||
// {
|
||||
// _collectionView.EndDefer();
|
||||
// _collectionView = null;
|
||||
// }
|
||||
//
|
||||
// GC.SuppressFinalize(this);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates a comparer class that takes in a CultureInfo as a parameter,
|
||||
// /// which it will use when comparing strings.
|
||||
// /// </summary>
|
||||
// private class CultureSensitiveComparer : IComparer<object>
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Private accessor for the CultureInfo of our comparer
|
||||
// /// </summary>
|
||||
// private CultureInfo _culture;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates a comparer which will respect the CultureInfo
|
||||
// /// that is passed in when comparing strings.
|
||||
// /// </summary>
|
||||
// /// <param name="culture">The CultureInfo to use in string comparisons</param>
|
||||
// public CultureSensitiveComparer(CultureInfo? culture)
|
||||
// {
|
||||
// _culture = culture ?? CultureInfo.InvariantCulture;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Compares two objects and returns a value indicating whether one is less than, equal to or greater than the other.
|
||||
// /// </summary>
|
||||
// /// <param name="x">first item to compare</param>
|
||||
// /// <param name="y">second item to compare</param>
|
||||
// /// <returns>Negative number if x is less than y, zero if equal, and a positive number if x is greater than y</returns>
|
||||
// /// <remarks>
|
||||
// /// Compares the 2 items using the specified CultureInfo for string and using the default object comparer for all other objects.
|
||||
// /// </remarks>
|
||||
// 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<object>.Default.Compare(x, y);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
+4
-4
@@ -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<object>();
|
||||
+31
-31
@@ -5,24 +5,24 @@ using Avalonia;
|
||||
|
||||
namespace AtomUI.Controls.Data;
|
||||
|
||||
internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup
|
||||
internal class ListBoxCollectionViewGroupInternal : ListBoxCollectionViewGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// GroupDescription used to define how to group the items
|
||||
/// </summary>
|
||||
private SelectGroupDescription? _groupBy;
|
||||
private ListBoxGroupDescription? _groupBy;
|
||||
|
||||
/// <summary>
|
||||
/// Parent group of this SelectCollectionViewGroupInternal
|
||||
/// Parent group of this ListBoxCollectionViewGroupInternal
|
||||
/// </summary>
|
||||
private readonly SelectCollectionViewGroupInternal? _parentGroup;
|
||||
private readonly ListBoxCollectionViewGroupInternal? _parentGroup;
|
||||
|
||||
/// <summary>
|
||||
/// Used for detecting stale enumerators
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="group">Empty subgroup to remove</param>
|
||||
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
|
||||
/// <param name="delta">Delta to change count by</param>
|
||||
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.
|
||||
/// </summary>
|
||||
/// <param name="group">CollectionViewGroupInternal that uses the enumerator</param>
|
||||
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
|
||||
|
||||
// / <summary>
|
||||
// / 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.
|
||||
// / </summary>
|
||||
@@ -604,10 +604,10 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for the CollectionViewGroupComparer that takes
|
||||
/// in an SelectCollectionViewGroupRoot.
|
||||
/// in an ListBoxCollectionViewGroupRoot.
|
||||
/// </summary>
|
||||
/// <param name="group">SelectCollectionViewGroupRoot used to compare on</param>
|
||||
internal CollectionViewGroupComparer(SelectCollectionViewGroupRoot group)
|
||||
/// <param name="group">ListBoxCollectionViewGroupRoot used to compare on</param>
|
||||
internal CollectionViewGroupComparer(ListBoxCollectionViewGroupRoot group)
|
||||
{
|
||||
_group = group;
|
||||
_index = 0;
|
||||
@@ -624,11 +624,11 @@ internal class SelectCollectionViewGroupInternal : SelectCollectionViewGroup
|
||||
|
||||
/// <summary>
|
||||
/// Sets our group to a new instance of a
|
||||
/// SelectCollectionViewGroupRoot being passed in
|
||||
/// ListBoxCollectionViewGroupRoot being passed in
|
||||
/// and resets the index.
|
||||
/// </summary>
|
||||
/// <param name="group">SelectCollectionViewGroupRoot used to compare on</param>
|
||||
internal void ResetGroup(SelectCollectionViewGroupRoot group)
|
||||
/// <param name="group">ListBoxCollectionViewGroupRoot used to compare on</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
+28
-28
@@ -6,7 +6,7 @@ using Avalonia.Collections;
|
||||
|
||||
namespace AtomUI.Controls.Data;
|
||||
|
||||
internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal, INotifyCollectionChanged
|
||||
internal class ListBoxCollectionViewGroupRoot : ListBoxCollectionViewGroupInternal, INotifyCollectionChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// String constant used for the Root Name
|
||||
@@ -21,12 +21,12 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal
|
||||
/// <summary>
|
||||
/// Private accessor for the top level GroupDescription
|
||||
/// </summary>
|
||||
private static SelectGroupDescription? _topLevelGroupDescription;
|
||||
private static ListBoxGroupDescription? _topLevelGroupDescription;
|
||||
|
||||
/// <summary>
|
||||
/// Private accessor for an ObservableCollection containing group descriptions
|
||||
/// </summary>
|
||||
private readonly AvaloniaList<SelectGroupDescription> _groupBy = new ();
|
||||
private readonly AvaloniaList<ListBoxGroupDescription> _groupBy = new ();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the list of items (after applying the sort and filters, if any)
|
||||
@@ -37,7 +37,7 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal
|
||||
/// <summary>
|
||||
/// Private accessor for the owning ICollectionView
|
||||
/// </summary>
|
||||
private readonly ISelectOptionCollectionView _view;
|
||||
private readonly IListBoxCollectionView _view;
|
||||
|
||||
/// <summary>
|
||||
/// Raise this event when the (grouped) view changes
|
||||
@@ -50,11 +50,11 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal
|
||||
internal event EventHandler? GroupDescriptionChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SelectCollectionViewGroupRoot class.
|
||||
/// Initializes a new instance of the ListBoxCollectionViewGroupRoot class.
|
||||
/// </summary>
|
||||
/// <param name="view">CollectionView that contains this grouping</param>
|
||||
/// <param name="isDataInGroupOrder">True if items are already in correct order for grouping</param>
|
||||
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
|
||||
/// <summary>
|
||||
/// Gets the description of grouping, indexed by level.
|
||||
/// </summary>
|
||||
public virtual AvaloniaList<SelectGroupDescription> GroupDescriptions => _groupBy;
|
||||
public virtual AvaloniaList<ListBoxGroupDescription> GroupDescriptions => _groupBy;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current IComparer being used
|
||||
@@ -229,16 +229,16 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal
|
||||
/// <param name="level">The level of grouping.</param>
|
||||
/// <param name="key">Name of subgroup to add to</param>
|
||||
/// <param name="loading">Whether we are currently loading</param>
|
||||
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
|
||||
/// <param name="group">Group to add item to</param>
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <param name="loading">Whether we are currently loading</param>
|
||||
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<SelectCollectionViewGroup, int, SelectGroupDescription>? GroupBySelector { get; set; }
|
||||
public virtual Func<ListBoxCollectionViewGroup, int, ListBoxGroupDescription>? GroupBySelector { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the description of how to divide the given group into subgroups
|
||||
@@ -330,10 +330,10 @@ internal class SelectCollectionViewGroupRoot : SelectCollectionViewGroupInternal
|
||||
/// <param name="group">CollectionViewGroup to get group description from</param>
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <returns>GroupDescription of how to divide the given group</returns>
|
||||
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
|
||||
/// <param name="groupDescription">GroupDescription for the group</param>
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <returns>Group names for the specified item</returns>
|
||||
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
|
||||
/// <param name="group">Group to initialize</param>
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <param name="seedItem">The seed item to compare with to see where to insert</param>
|
||||
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
|
||||
/// <param name="group">Group to remove item from</param>
|
||||
/// <param name="item">Item to remove</param>
|
||||
/// <returns>True if item could not be removed</returns>
|
||||
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
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <param name="key">Name of item to remove</param>
|
||||
/// <returns>Return true if the item was not in one of the subgroups it was supposed to be.</returns>
|
||||
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
|
||||
/// <param name="group">Group to remove item from</param>
|
||||
/// <param name="level">The level of grouping</param>
|
||||
/// <returns>Return true if the item was not in one of the subgroups it was supposed to be.</returns>
|
||||
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
|
||||
/// </summary>
|
||||
/// <param name="group">Group to remove item from</param>
|
||||
/// <param name="item">Item to remove</param>
|
||||
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
|
||||
/// <summary>
|
||||
/// TopLevelGroupDescription class
|
||||
/// </summary>
|
||||
private class TopLevelGroupDescription : SelectGroupDescription
|
||||
private class TopLevelGroupDescription : ListBoxGroupDescription
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TopLevelGroupDescription class.
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
namespace AtomUI.Controls.Data;
|
||||
|
||||
internal class SelectDefaultFilter
|
||||
internal class ListBoxDefaultFilter
|
||||
{
|
||||
private readonly WeakReference<ISelectOptionCollectionView> CollectionViewRef;
|
||||
private readonly WeakReference<IListBoxCollectionView> CollectionViewRef;
|
||||
|
||||
public SelectDefaultFilter(ISelectOptionCollectionView collectionView)
|
||||
public ListBoxDefaultFilter(IListBoxCollectionView collectionView)
|
||||
{
|
||||
CollectionViewRef = new WeakReference<ISelectOptionCollectionView>(collectionView);
|
||||
CollectionViewRef = new WeakReference<IListBoxCollectionView>(collectionView);
|
||||
}
|
||||
|
||||
public bool Filter(object value)
|
||||
@@ -31,7 +31,7 @@ internal class SelectDefaultFilter
|
||||
return false;
|
||||
}
|
||||
|
||||
public static implicit operator Func<object, bool>(SelectDefaultFilter filter)
|
||||
public static implicit operator Func<object, bool>(ListBoxDefaultFilter filter)
|
||||
{
|
||||
return filter.Filter;
|
||||
}
|
||||
+2
-2
@@ -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<SelectFilterDescription> {}
|
||||
public class SelectFilterDescriptionCollection : AvaloniaList<ListBoxFilterDescription> {}
|
||||
+2
-2
@@ -4,11 +4,11 @@ using Avalonia.Collections;
|
||||
|
||||
namespace AtomUI.Controls.Data;
|
||||
|
||||
public abstract class SelectGroupDescription : INotifyPropertyChanged
|
||||
public abstract class ListBoxGroupDescription : INotifyPropertyChanged
|
||||
{
|
||||
public AvaloniaList<object> GroupKeys { get; }
|
||||
|
||||
public SelectGroupDescription()
|
||||
public ListBoxGroupDescription()
|
||||
{
|
||||
GroupKeys = new AvaloniaList<object>();
|
||||
GroupKeys.CollectionChanged += (sender, e) => OnPropertyChanged(new PropertyChangedEventArgs(nameof(GroupKeys)));
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
+18
-18
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<object> 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<IComparer<object>>(() => Comparer<object>.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<object> 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<SelectSortDescription> {}
|
||||
public class SelectSortDescriptionCollection : AvaloniaList<ListBoxSortDescription> {}
|
||||
Reference in New Issue
Block a user