Сделать сортировку коллекции вместо создания новой коллекции с передачей IOrderedEnumerable - C#
Формулировка задачи:
Есть:
И есть способ сортировки объектов внутри коллекции:
Вот как сделать так, чтобы можно было не передавать в конструктор отсортированную коллекцию, а сортировать эту.
Я конечно попробую разобраться, когда время найду, но было бы неплохо, если бы кто-то подсказал.
----------------------------------------------------------------------------------------------------------------
SortableObservableCollection<T>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace UI.Base.Collections.ObjectModel
{
/// <summary>
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed and allows sorting.
/// </summary>
/// <typeparam name="T">The type of elements in the collection.</typeparam>
public class SortableObservableCollection<T> : ObservableCollection<T>
{
public SortableObservableCollection()
{
}
public SortableObservableCollection(List<T> list)
: base((IList<T>)list)
{
}
/// <summary>
/// Sorts the items of the collection in ascending order according to a key.
/// </summary>
/// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
/// <param name="keySelector">A function to extract a key from an item.</param>
public void Sort<TKey>(Func<T, TKey> keySelector)
{
InternalSort(Items.OrderBy(keySelector));
}
/// <summary>
/// Sorts the items of the collection in ascending order according to a key.
/// </summary>
/// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
/// <param name="keySelector">A function to extract a key from an item.</param>
/// <param name="comparer">An <see cref="IComparer{T}"/> to compare keys.</param>
public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{
InternalSort(Items.OrderBy(keySelector, comparer));
}
/// <summary>
/// Moves the items of the collection so that their orders are the same as those of the items provided.
/// </summary>
/// <param name="sortedItems">An <see cref="IEnumerable{T}"/> to provide item orders.</param>
private void InternalSort(IEnumerable<T> sortedItems)
{
var sortedItemsList = sortedItems.ToList();
foreach (var item in sortedItemsList)
{
Move(IndexOf(item), sortedItemsList.IndexOf(item));
}
}
}
} private void MainQueueeAppsToCollectionsAsViewModel(IEnumerable<Application> apps, int[] runnigIds)
{
SendedApps.Clear();
foreach (Application app in apps)
{
var vm = new ApplicationViewModel(app);
vm.Running = runnigIds.Any(id => vm.Id == id);
vm.StartListenPropertyChanging();
SendedApps.Add(vm);
}
//Сортируем
List<ApplicationViewModel> sorted = SendedApps
.OrderByDescending(e => e.IsCompleted)
.ThenBy(e => e.Order)
.ToList();
//Создаём новую коллекцию
SendedApps = new SortableObservableCollection<ApplicationViewModel>(sorted);
}
Кажись я понял. Самое простое это:
Новый метод в SortableObservableCollection, код которой выложен выше:
public void Sort(IOrderedEnumerable<T> ordered)
{
var sortedItemsList = ordered.ToList();
foreach (var item in sortedItemsList)
{
Move(IndexOf(item), sortedItemsList.IndexOf(item));
}
} private void MainQueueeAppsToCollectionsAsViewModel(IEnumerable<Application> apps, int[] runnigIds)
{
//какой-то код...
IOrderedEnumerable<ApplicationViewModel> sorted = SendedApps
.OrderByDescending(e => e.IsCompleted)
.ThenBy(e => e.Order);
SendedApps.Sort(sorted);
} Решение задачи: «Сделать сортировку коллекции вместо создания новой коллекции с передачей IOrderedEnumerable»
textual
Листинг программы
public class SortableObservableCollection<T> : ObservableCollection<T>
{
private readonly IComparer<T> _comparer;
public SortableObservableCollection(IComparer<T> comparer)
{
_comparer = comparer;
}
public SortableObservableCollection(Comparison<T> comparison)
: this(Comparer<T>.Create(comparison))
{
}
public void Sort()
{
var list = Items as List<T>;
if (list != null)
{
list.Sort(_comparer);
return;
}
var arr = Items.ToArray();
Array.Sort(arr, _comparer);
var oldIndices = new Dictionary<T, int>();
int i = 0;
foreach (var item in Items)
{
oldIndices.Add(item, i++);
}
for (int j = 0; j < arr.Length; j++)
{
Move(oldIndices[arr[j]], j);
}
}
}