Сведения о вопросе

krutoi

23:52, 14th August, 2020

Теги

c#   .net   wpf   data-binding   collections    

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

Просмотров: 443   Ответов: 3

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

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

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

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

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

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



  Сведения об ответе

darknet

15:25, 12th August, 2020

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

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

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


  Сведения об ответе

darknet

07:11, 11th August, 2020

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


  Сведения об ответе

#hash

16:34, 18th August, 2020

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

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

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться