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

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

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

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

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

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

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

3 ответа

Решение

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

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

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

Я еще не очень знаком с 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);
}

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

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

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

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

Другие вопросы по тегам