Сортировка составной коллекции - PullRequest
7 голосов
/ 14 августа 2008

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

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

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

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

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

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

Ответы [ 3 ]

1 голос
/ 14 августа 2008

Я еще не очень знаком с 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 голос
/ 23 августа 2008

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

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

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

1 голос
/ 14 августа 2008

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

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

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

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

...