From f7fc8639af2ad244d61efec89603fed411bdedef Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Wed, 1 Jun 2022 17:17:44 +0200 Subject: [PATCH 1/2] Add: Ability to reorder collections by dragging them around --- .../Controls/CollectionListingPresenter.cs | 25 ++++++- .../Controls/CombinedListingPresenter.cs | 6 +- App/Presenters/Forms/MainFormPresenter.cs | 2 +- App/Properties/Settings.Designer.cs | 14 +++- App/Properties/Settings.settings | 3 + App/app.config | 3 + CollectionManagerDll/Enums/CollectionEdit.cs | 1 + .../CollectionsManager/CollectionEditArgs.cs | 13 ++++ .../CollectionsManager/CollectionsManager.cs | 64 ++++++++++++++++- Common/GuiHelpers.cs | 1 + .../Controls/ICollectionListingView.cs | 1 + .../CollectionListingView.Designer.cs | 1 + .../Controls/CollectionListingView.cs | 70 ++++++++++++++++--- 13 files changed, 186 insertions(+), 18 deletions(-) diff --git a/App/Presenters/Controls/CollectionListingPresenter.cs b/App/Presenters/Controls/CollectionListingPresenter.cs index d8fb831..8d10d84 100644 --- a/App/Presenters/Controls/CollectionListingPresenter.cs +++ b/App/Presenters/Controls/CollectionListingPresenter.cs @@ -7,6 +7,8 @@ using System.Windows.Forms; using System.Collections.Specialized; using App.Misc; +using Common; +using App.Properties; namespace App.Presenters.Controls { @@ -15,7 +17,8 @@ public class CollectionListingPresenter ICollectionListingView _view; private Collections _collections; - private ICollectionListingModel _model; + private readonly ICollectionListingModel _model; + private readonly IUserDialogs _userDialogs; public Collections Collections { @@ -32,23 +35,39 @@ public Collections Collections _view.SelectedCollection = selectedCollection; } } - public CollectionListingPresenter(ICollectionListingView view, ICollectionListingModel model) + public CollectionListingPresenter(ICollectionListingView view, ICollectionListingModel model, IUserDialogs userDialogs) { _view = view; _view.RightClick += _view_RightClick; _view.SelectedCollectionsChanged += ViewOnSelectedCollectionsChanged; _view.BeatmapsDropped += ViewOnBeatmapsDropped; + _view.OnCollectionReorder += ViewOnCollectionReorder; _model = model; + _userDialogs = userDialogs; _model.CollectionsChanged += ModelOnCollectionsChanged; Collections = _model.GetCollections(); } + private void ViewOnCollectionReorder(object sender, Collections collections, Collection targetCollection, bool placeBefore) + { + if (!Settings.Default.DontAskAboutReorderingCollections) + { + var result = _userDialogs.YesNoMessageBox($"Reordering collections will rename all loaded collections, proceed?", "Reordering", MessageBoxType.Question, + "Don't ask me again"); + Settings.Default.DontAskAboutReorderingCollections = result.doNotAskAgain; + Settings.Default.Save(); + if (!result.Result) + return; + } + + _model.EmitCollectionEditing(CollectionEditArgs.ReorderCollections(collections, targetCollection, placeBefore)); + } + private void ViewOnBeatmapsDropped(object sender, Beatmaps args, string collectionName) { _model.EmitCollectionEditing(CollectionEditArgs.AddBeatmaps(collectionName, args)); } - private void ViewOnSelectedCollectionsChanged(object sender, EventArgs eventArgs) { Collections selectedCollections = new Collections(); diff --git a/App/Presenters/Controls/CombinedListingPresenter.cs b/App/Presenters/Controls/CombinedListingPresenter.cs index 2bfa93f..33e5c59 100644 --- a/App/Presenters/Controls/CombinedListingPresenter.cs +++ b/App/Presenters/Controls/CombinedListingPresenter.cs @@ -14,9 +14,10 @@ public class CombinedListingPresenter private readonly ICollectionListingView _collectionsView; public readonly IBeatmapListingModel BeatmapListingModel; private readonly IWebCollectionProvider _webCollectionProvider; + private readonly IUserDialogs _userDialogs; private readonly ICollectionListingModel _collectionListingModel; - public CombinedListingPresenter(ICombinedListingView view, ICollectionListingModel collectionListingModel, IBeatmapListingModel beatmapListingModel, IWebCollectionProvider webCollectionProvider) + public CombinedListingPresenter(ICombinedListingView view, ICollectionListingModel collectionListingModel, IBeatmapListingModel beatmapListingModel, IWebCollectionProvider webCollectionProvider, IUserDialogs userDialogs) { _view = view; _beatmapsView = _view.beatmapListingView; @@ -26,8 +27,9 @@ public CombinedListingPresenter(ICombinedListingView view, ICollectionListingMod BeatmapListingModel = beatmapListingModel; _webCollectionProvider = webCollectionProvider; + _userDialogs = userDialogs; new BeatmapListingPresenter(_beatmapsView, BeatmapListingModel); - new CollectionListingPresenter(_collectionsView, collectionListingModel); + new CollectionListingPresenter(_collectionsView, collectionListingModel, userDialogs); BeatmapListingModel.SelectedBeatmapsChanged += BeatmapListingModelOnSelectedBeatmapsChanged; _collectionsView.SelectedCollectionChanged += CollectionsViewOnSelectedCollectionChanged; diff --git a/App/Presenters/Forms/MainFormPresenter.cs b/App/Presenters/Forms/MainFormPresenter.cs index 11d3415..3f821e1 100644 --- a/App/Presenters/Forms/MainFormPresenter.cs +++ b/App/Presenters/Forms/MainFormPresenter.cs @@ -33,7 +33,7 @@ public MainFormPresenter(IMainFormView view, IMainFormModel mainFormModel, IInfo CollectionListingModel = new CollectionListingModel(Initalizer.LoadedCollections, _mainFormModel.GetCollectionEditor()); CollectionListingModel.CollectionEditing += CollectionListing_CollectionEditing; CollectionListingModel.SelectedCollectionsChanged += CollectionListing_SelectedCollectionsChanged; - new CombinedListingPresenter(_view.CombinedListingView, CollectionListingModel, BeatmapListingModel, webCollectionProvider); + new CombinedListingPresenter(_view.CombinedListingView, CollectionListingModel, BeatmapListingModel, webCollectionProvider, mainFormModel.GetUserDialogs()); //Beatmap preview stuff (images, beatmap info like ar,cs,stars...) _combinedBeatmapPreviewModel = new CombinedBeatmapPreviewModel(); diff --git a/App/Properties/Settings.Designer.cs b/App/Properties/Settings.Designer.cs index 218d51d..3f7ff11 100644 --- a/App/Properties/Settings.Designer.cs +++ b/App/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace App.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.1.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -106,5 +106,17 @@ public string DownloadManager_DownloaderSettings { this["DownloadManager_DownloaderSettings"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool DontAskAboutReorderingCollections { + get { + return ((bool)(this["DontAskAboutReorderingCollections"])); + } + set { + this["DontAskAboutReorderingCollections"] = value; + } + } } } diff --git a/App/Properties/Settings.settings b/App/Properties/Settings.settings index 452c5bb..8a5b9da 100644 --- a/App/Properties/Settings.settings +++ b/App/Properties/Settings.settings @@ -23,5 +23,8 @@ {} + + False + \ No newline at end of file diff --git a/App/app.config b/App/app.config index 214ccb9..799efb4 100644 --- a/App/app.config +++ b/App/app.config @@ -29,6 +29,9 @@ {} + + False + diff --git a/CollectionManagerDll/Enums/CollectionEdit.cs b/CollectionManagerDll/Enums/CollectionEdit.cs index 192249e..5ebe12b 100644 --- a/CollectionManagerDll/Enums/CollectionEdit.cs +++ b/CollectionManagerDll/Enums/CollectionEdit.cs @@ -14,5 +14,6 @@ public enum CollectionEdit Intersect=9, Inverse=10, Difference=11, + Reorder=12, } } \ No newline at end of file diff --git a/CollectionManagerDll/Modules/CollectionsManager/CollectionEditArgs.cs b/CollectionManagerDll/Modules/CollectionsManager/CollectionEditArgs.cs index 1b94db5..0653330 100644 --- a/CollectionManagerDll/Modules/CollectionsManager/CollectionEditArgs.cs +++ b/CollectionManagerDll/Modules/CollectionsManager/CollectionEditArgs.cs @@ -11,8 +11,10 @@ public class CollectionEditArgs : EventArgs public string OrginalName { get; private set; } public string NewName { get; set; } public Collections Collections { get; private set; } + public Collection TargetCollection { get; private set; } public Beatmaps Beatmaps { get; private set; } public IList CollectionNames { get; private set; } + public bool PlaceCollectionsBefore { get; private set; } public CollectionEditArgs(CollectionEdit action) { Action = action; @@ -114,6 +116,17 @@ public static CollectionEditArgs AddBeatmaps(string collectionName, Beatmaps bea }; } + #endregion + #region Reorder collections using special characters placed at the begining of the name, this modifies ALL collection names + public static CollectionEditArgs ReorderCollections(Collections collections, Collection targetCollection, bool placeBefore) + { + return new CollectionEditArgs(CollectionEdit.Reorder) + { + Collections = collections, + TargetCollection = targetCollection, + PlaceCollectionsBefore = placeBefore + }; + } #endregion #region Remove beatmaps from collection public static CollectionEditArgs RemoveBeatmaps(string collectionName, Beatmaps beatmaps) diff --git a/CollectionManagerDll/Modules/CollectionsManager/CollectionsManager.cs b/CollectionManagerDll/Modules/CollectionsManager/CollectionsManager.cs index 149a995..9861f13 100644 --- a/CollectionManagerDll/Modules/CollectionsManager/CollectionsManager.cs +++ b/CollectionManagerDll/Modules/CollectionsManager/CollectionsManager.cs @@ -1,6 +1,7 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; +using System.Text; using App.Interfaces; using CollectionManager.DataTypes; using CollectionManager.Enums; @@ -12,10 +13,18 @@ public class CollectionsManager : ICollectionEditor, ICollectionNameValidator { public readonly Collections LoadedCollections = new Collections(); public Beatmaps LoadedBeatmaps; + private readonly char[] ReorderChars; + private readonly char[] ReorderCharsWithSeparator; + private readonly string ReorderCharsString; + private const string reorderSeparator = "| "; public CollectionsManager(Beatmaps loadedBeatmaps) { LoadedBeatmaps = loadedBeatmaps; + ReorderCharsString = "0123456789";//!$)]},.? ABCDEFGHIJKLMNOPQRSTUVWXYZ @#%^&*(+[{;':\\\"<>/ + ReorderChars = ReorderCharsString.ToArray(); + ReorderCharsWithSeparator = ReorderChars.Concat(reorderSeparator).ToArray(); } + /* add collection remove collection @@ -25,10 +34,10 @@ intersect x collections inverse map sum of x collections difference x collections clear collections + reorder collections add beatmaps to collection remove beatmaps from collection */ - private void EditCollection(CollectionEditArgs args, bool suspendRefresh = false) { var action = args.Action; @@ -151,6 +160,36 @@ private void EditCollection(CollectionEditArgs args, bool suspendRefresh = false { LoadedCollections.Clear(); } + else if (action == CollectionEdit.Reorder) + { + var targetCollection = args.TargetCollection; + var collectionsToReorder = args.Collections.OrderBy(x => x.Name).ToList(); + var orderedLoadedCollections = LoadedCollections.OrderBy(x => x.Name).ToList(); + foreach (var coll in collectionsToReorder) + orderedLoadedCollections.Remove(coll); + + var targetCollectionIndex = orderedLoadedCollections.IndexOf(targetCollection); + orderedLoadedCollections.InsertRange(args.PlaceCollectionsBefore ? targetCollectionIndex : targetCollectionIndex + 1, collectionsToReorder); + var amountOfCharactersRequired = 0; + var variations = 0; + while (orderedLoadedCollections.Count() > variations) + variations = Enumerable.Range(1, ++amountOfCharactersRequired).Aggregate(0, (acc, i) => Convert.ToInt32(Math.Pow(ReorderChars.Length, i)) + acc); + + List reorderStrings = new List(variations); + for (int i = 1; i <= amountOfCharactersRequired; i++) + reorderStrings.AddRange(CombinationsWithRepetition(ReorderCharsString, i)); + + reorderStrings.Sort(); + var collectionIndex = 0; + foreach (var collection in orderedLoadedCollections) + { + + if (collection.Name.Contains(reorderSeparator)) + collection.Name = collection.Name.TrimStart(ReorderCharsWithSeparator); + + collection.Name = $"{reorderStrings[collectionIndex++]}{reorderSeparator} {collection.Name}"; + } + } else { var collection = GetCollectionByName(args.OrginalName); @@ -243,5 +282,26 @@ public bool IsCollectionNameValid(string name) { return !CollectionNameExists(name); } + + private static string Combinations(string symbols, int number, int stringLength) + { + var stringBuilder = new StringBuilder(); + var len = symbols.Length; + var nullSym = symbols[0]; + while (number > 0) + { + var index = number % len; + number = number / len; + stringBuilder.Insert(0, symbols[index]); + } + + return stringBuilder.ToString().PadLeft(stringLength, nullSym); + } + + private static IEnumerable CombinationsWithRepetition(string symbols, int stringLength) + { + for (var i = 0; i < Math.Pow(symbols.Length, stringLength); i++) + yield return Combinations(symbols, i, stringLength); + } } } \ No newline at end of file diff --git a/Common/GuiHelpers.cs b/Common/GuiHelpers.cs index 1799ada..d162567 100644 --- a/Common/GuiHelpers.cs +++ b/Common/GuiHelpers.cs @@ -7,6 +7,7 @@ public static class GuiHelpers { public delegate void BeatmapsEventArgs(object sender, Beatmaps args); public delegate void CollectionBeatmapsEventArgs(object sender, Beatmaps args, string collectionName); + public delegate void CollectionReorderEventArgs(object sender, Collections collections, Collection targetCollection, bool placeBefore); public delegate void BeatmapListingActionArgs(object sender, BeatmapListingAction args); public delegate void SidePanelActionsHandlerArgs(object sender, MainSidePanelActions args, object data = null); public delegate void LoadFileArgs(object sender, string[] filePaths); diff --git a/Common/Interfaces/Controls/ICollectionListingView.cs b/Common/Interfaces/Controls/ICollectionListingView.cs index bd29dab..e2415e2 100644 --- a/Common/Interfaces/Controls/ICollectionListingView.cs +++ b/Common/Interfaces/Controls/ICollectionListingView.cs @@ -9,6 +9,7 @@ namespace GuiComponents.Interfaces public interface ICollectionListingView { event GuiHelpers.LoadFileArgs OnLoadFile; + event GuiHelpers.CollectionReorderEventArgs OnCollectionReorder; string SearchText { get; } diff --git a/GuiComponents/Controls/CollectionListingView.Designer.cs b/GuiComponents/Controls/CollectionListingView.Designer.cs index 7b06654..b76e327 100644 --- a/GuiComponents/Controls/CollectionListingView.Designer.cs +++ b/GuiComponents/Controls/CollectionListingView.Designer.cs @@ -91,6 +91,7 @@ private void InitializeComponent() this.ListViewCollections.Name = "ListViewCollections"; this.ListViewCollections.ShowGroups = false; this.ListViewCollections.Size = new System.Drawing.Size(463, 345); + this.ListViewCollections.Sorting = System.Windows.Forms.SortOrder.Ascending; this.ListViewCollections.TabIndex = 5; this.ListViewCollections.UnfocusedHighlightBackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192))))); this.ListViewCollections.UseCompatibleStateImageBehavior = false; diff --git a/GuiComponents/Controls/CollectionListingView.cs b/GuiComponents/Controls/CollectionListingView.cs index 6daebbd..6d1060d 100644 --- a/GuiComponents/Controls/CollectionListingView.cs +++ b/GuiComponents/Controls/CollectionListingView.cs @@ -1,6 +1,5 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; @@ -15,8 +14,18 @@ namespace GuiComponents.Controls public partial class CollectionListingView : UserControl, ICollectionListingView { public event GuiHelpers.LoadFileArgs OnLoadFile; + public event GuiHelpers.CollectionReorderEventArgs OnCollectionReorder; + public string SearchText => textBox_collectionNameSearch.Text; - public Collections Collections { set { ListViewCollections.SetObjects(value); } } + public Collections Collections + { + set + { + var selectedCollections = SelectedCollections; + ListViewCollections.SetObjects(value); + SelectedCollections = selectedCollections; + } + } public ICollection SelectedCollection { @@ -27,7 +36,15 @@ public ICollection SelectedCollection ListViewCollections.SelectedObject = value; } } - public ArrayList SelectedCollections => (ArrayList)ListViewCollections.SelectedObjects; + public ArrayList SelectedCollections + { + get => (ArrayList)ListViewCollections.SelectedObjects; + private set + { + ListViewCollections.SelectedObjects = value; + ListViewCollections.EnsureSelectionIsVisible(); + } + } public Collections HighlightedCollections { get => _collectionRenderer.Collections; @@ -38,7 +55,6 @@ public Collections HighlightedCollections } } - public event EventHandler SearchTextChanged; public event EventHandler SelectedCollectionChanged; public event EventHandler SelectedCollectionsChanged; @@ -77,8 +93,9 @@ private void init() ListViewCollections.FullRowSelect = true; ListViewCollections.HideSelection = false; ListViewCollections.DefaultRenderer = _collectionRenderer; - - _dropsink.CanDropBetween = false; + ListViewCollections.IsSimpleDragSource = true; + + _dropsink.CanDropBetween = true; _dropsink.CanDropOnItem = true; _dropsink.CanDropOnSubItem = false; _dropsink.CanDropOnBackground = false; @@ -123,6 +140,27 @@ private void DropsinkOnModelCanDrop(object sender, ModelDropEventArgs e) e.Handled = true; e.Effect = DragDropEffects.None; } + else if (e.SourceModels[0] is Collection) + { + + if (e.DropTargetLocation != DropTargetLocation.AboveItem && e.DropTargetLocation != DropTargetLocation.BelowItem) + { + e.Handled = true; + e.Effect = DragDropEffects.None; + } + else + { + var targetCollection = (Collection)e.TargetModel; + foreach (var model in e.SourceModels) + { + if (model == targetCollection) + { + e.Handled = true; + e.Effect = DragDropEffects.None; + } + } + } + } } } @@ -158,15 +196,29 @@ protected virtual void OnSelectedCollectionsChanged() private void ListViewCollections_ModelDropped(object sender, ModelDropEventArgs e) { e.Handled = true; - var collection = (Collection)e.TargetModel; - if (collection == null) return; + var targetCollection = (Collection)e.TargetModel; + if (e.SourceModels[0] is Collection) + { + var nameColumn = ListViewCollections.AllColumns[0]; + if (ListViewCollections.LastSortColumn != nameColumn || ListViewCollections.LastSortOrder != SortOrder.Ascending) + ListViewCollections.Sort(ListViewCollections.AllColumns[0], SortOrder.Ascending); + + var collections = new Collections(); + foreach (var collection in e.SourceModels) + collections.Add((Collection)collection); + + OnCollectionReorder?.Invoke(this, collections, targetCollection, e.DropTargetLocation == DropTargetLocation.AboveItem); + return; + } + + if (targetCollection == null) return; var beatmaps = new Beatmaps(); foreach (var b in e.SourceModels) { beatmaps.Add((BeatmapExtension)b); } - BeatmapsDropped?.Invoke(this, beatmaps, collection.Name); + BeatmapsDropped?.Invoke(this, beatmaps, targetCollection.Name); } protected virtual void OnRightClick(StringEventArgs e) From a9359ffdfce116787a27adf7a3742fc33f4382cf Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:02:30 +0200 Subject: [PATCH 2/2] Misc: Sort collections in alphabetical order by default --- CollectionManagerDll/DataTypes/Collection.cs | 2 +- GuiComponents/Controls/CollectionListingView.cs | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CollectionManagerDll/DataTypes/Collection.cs b/CollectionManagerDll/DataTypes/Collection.cs index a627c54..f8353cd 100644 --- a/CollectionManagerDll/DataTypes/Collection.cs +++ b/CollectionManagerDll/DataTypes/Collection.cs @@ -37,7 +37,7 @@ public class Collection : IEnumerable, ICollection /// public Beatmaps KnownBeatmaps { get; } = new Beatmaps(); - + public override string ToString() => $"osu! map Collection: \"{Name}\" Count: {BeatmapHashes.Count}"; /// /// Total number of beatmaps contained in this collection diff --git a/GuiComponents/Controls/CollectionListingView.cs b/GuiComponents/Controls/CollectionListingView.cs index 6d1060d..cde5e1f 100644 --- a/GuiComponents/Controls/CollectionListingView.cs +++ b/GuiComponents/Controls/CollectionListingView.cs @@ -15,7 +15,6 @@ public partial class CollectionListingView : UserControl, ICollectionListingView { public event GuiHelpers.LoadFileArgs OnLoadFile; public event GuiHelpers.CollectionReorderEventArgs OnCollectionReorder; - public string SearchText => textBox_collectionNameSearch.Text; public Collections Collections { @@ -61,6 +60,10 @@ public Collections HighlightedCollections public event GuiHelpers.CollectionBeatmapsEventArgs BeatmapsDropped; public event EventHandler RightClick; + private CollectionRenderer _collectionRenderer = new CollectionRenderer(); + private RearrangingDropSink _dropsink = new RearrangingDropSink(); + private OLVColumn NameColumn; + public CollectionListingView() { InitializeComponent(); @@ -83,9 +86,6 @@ private void Bind() } - private CollectionRenderer _collectionRenderer = new CollectionRenderer(); - private RearrangingDropSink _dropsink = new RearrangingDropSink(); - private void init() { //ListViewCollections.SelectedIndexChanged += ListViewCollectionsSelectedIndexChanged; @@ -94,6 +94,8 @@ private void init() ListViewCollections.HideSelection = false; ListViewCollections.DefaultRenderer = _collectionRenderer; ListViewCollections.IsSimpleDragSource = true; + ListViewCollections.PrimarySortColumn = NameColumn = ListViewCollections.AllColumns[0]; + ListViewCollections.PrimarySortOrder = SortOrder.Ascending; _dropsink.CanDropBetween = true; _dropsink.CanDropOnItem = true; @@ -189,18 +191,19 @@ protected virtual void OnSelectedCollectionChanged() { SelectedCollectionChanged?.Invoke(this, EventArgs.Empty); } + protected virtual void OnSelectedCollectionsChanged() { SelectedCollectionsChanged?.Invoke(this, EventArgs.Empty); } + private void ListViewCollections_ModelDropped(object sender, ModelDropEventArgs e) { e.Handled = true; var targetCollection = (Collection)e.TargetModel; if (e.SourceModels[0] is Collection) { - var nameColumn = ListViewCollections.AllColumns[0]; - if (ListViewCollections.LastSortColumn != nameColumn || ListViewCollections.LastSortOrder != SortOrder.Ascending) + if (ListViewCollections.LastSortColumn != NameColumn || ListViewCollections.LastSortOrder != SortOrder.Ascending) ListViewCollections.Sort(ListViewCollections.AllColumns[0], SortOrder.Ascending); var collections = new Collections();