Сортировка составной коллекции

Таким образом, WPF не поддерживает стандартное поведение сортировки или фильтрации для представлений CompositeCollections, так что было бы лучшим решением для решения этой проблемы.

Существует два или более наборов объектов разных типов. Вы хотите объединить их в одну сортируемую и фильтруемую коллекцию (без необходимости вручную сортировать или фильтровать).

Один из подходов, которые я рассмотрел, заключается в создании новой коллекции объектов только с несколькими основными свойствами, включая те, по которым я хочу отсортировать коллекцию, и экземпляром объекта каждого типа.

class MyCompositeObject
{
    enum           ObjectType;
    DateTime       CreatedDate;
    string         SomeAttribute;
    myObjectType1  Obj1;
    myObjectType2  Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }

А затем переберите мои две коллекции объектов для создания новой составной коллекции. Очевидно, это немного грубый метод, но он бы сработал. Я получал бы все поведение сортировки и фильтрации представлений по умолчанию для моей новой коллекции составных объектов, и я мог бы поместить в нее шаблон данных, чтобы правильно отображать элементы списка в зависимости от того, какой тип фактически хранится в этом составном элементе.

Какие есть предложения, чтобы сделать это более элегантно?

14.08.2008 16:30:49
3 ОТВЕТА

Метод "грубой силы", который вы упоминаете, на самом деле идеальное решение. Имейте в виду, что все объекты находятся в оперативной памяти, узких мест ввода / вывода нет, поэтому вы можете в значительной степени сортировать и фильтровать миллионы объектов менее чем за секунду на любом современном компьютере.

Самый элегантный способ работы с коллекциями - это пространство имен System.Linq в .NET 3.5

Спасибо - я также рассмотрел LINQ для объектов, но меня беспокоит потеря гибкости для типизированных шаблонов данных, которые мне нужны для отображения объектов в моем списке.

Если в данный момент вы не можете предсказать, как люди будут сортировать и фильтровать вашу коллекцию объектов, вам следует взглянуть на пространство имен System.Linq.Expressions, чтобы создавать лямбда-выражения по требованию во время выполнения (сначала вы позволяете пользователю создавать выражения, а затем компилируете , запустите и в конце вы используете пространство имен отражения для перечисления результатов). Сложнее обернуть вокруг него голову, но это бесценная особенность, вероятно (для меня определенно) даже более новаторская, чем сама LINQ.

1
14.08.2008 22:20:22
lubos: Спасибо. Я также рассмотрел LINQ для объектов, но меня беспокоит потеря гибкости для типизированных шаблонов данных, которые необходимы для отображения объектов в моем списке.
Christopher Scott 19.01.2010 04:05:11

Я еще не очень знаком с WPF, но вижу в этом вопрос о сортировке и фильтрации List<T>коллекций.

(без необходимости вручную сортировать или фильтровать)

Вы бы пересмотрели реализацию своих собственных функций сортировки или фильтрации? По моему опыту это легко использовать. В приведенных ниже примерах используется анонимный делегат, но вы можете легко определить свой собственный метод или класс для реализации сложной сортировки или фильтра. Такой класс может даже иметь свойства для настройки, изменения сортировки и динамической фильтрации.

Используйте List<T>.Sort(Comparison<T> comparison)с вашей пользовательской функцией сравнения:

// Sort according to the value of SomeAttribute
List<MyCompositeObject> myList = ...;
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b) 
{
    // return -1 if a < b
    // return 0 if a == b
    // return 1 if a > b
    return a.SomeAttribute.CompareTo(b.SomeAttribute);
};

Аналогичный подход для получения вложенной коллекции предметов из списка.

Используйте List<T>.FindAll(Predicate<T> match)с вашей пользовательской функцией фильтра:

// Select all objects where myObjectType1 and myObjectType2 are not null
myList.FindAll(delegate(MyCompositeObject a)
{
    // return true to include 'a' in the sub-collection
    return (a.myObjectType1 != null) && (a.myObjectType2 != null);
}
1
14.08.2008 18:37:22
Брайан: После создания MyCompositeObject я получаю бесплатную сортировку и фильтрацию как часть ICollectionView. Суть проблемы заключается в работе с отдельными коллекциями типов объектов и обработкой их как одной коллекции. Составные коллекции - это ответ для создания коллекции, но не для фильтрации сортировки.
Christopher Scott 19.01.2010 04:06:13
РЕШЕНИЕ

Обновление: я нашел гораздо более элегантное решение:

class MyCompositeObject
{
    DateTime    CreatedDate;
    string      SomeAttribute;
    Object      Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }

Я обнаружил, что благодаря размышлениям конкретный тип, хранящийся в Obj1, разрешается во время выполнения, а типоспецифичный тип DataTemplate применяется, как и ожидалось!

1
23.08.2008 03:48:11