Pergunta

Portanto, o WPF não oferece suporte ao comportamento padrão de classificação ou filtragem para visualizações de CompositeCollections, então qual seria a prática recomendada para resolver esse problema.

Existem duas ou mais coleções de objetos de tipos diferentes.Você deseja combiná-los em uma única coleção classificável e filtrável (sem ter que implementar manualmente a classificação ou filtro).

Uma das abordagens que considerei é criar uma nova coleção de objetos com apenas algumas propriedades principais, incluindo aquelas nas quais eu gostaria que a coleção fosse classificada e uma instância de objeto de cada tipo.

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

E então percorra minhas duas coleções de objetos para construir a nova coleção composta.Obviamente, este é um método de força bruta, mas funcionaria.Eu obteria todo o comportamento padrão de classificação e filtragem de visualização em minha nova coleção de objetos compostos e seria capaz de colocar um modelo de dados nela para exibir meus itens de lista corretamente, dependendo de qual tipo está realmente armazenado naquele item composto.

Que sugestões existem para fazer isso de uma forma mais elegante?

Foi útil?

Solução 3

Atualizar:Encontrei uma solução muito mais elegante:

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

Descobri que, devido à reflexão, o tipo específico armazenado em Obj1 é resolvido em tempo de execução e o DataTemplate específico do tipo é aplicado conforme esperado!

Outras dicas

Ainda não estou muito familiarizado com o WPF, mas vejo isso como uma questão sobre classificação e filtragem List<T> coleções.

(sem ter que implementar manualmente classificação ou filtro)

Você reconsideraria a implementação de suas próprias funções de classificação ou filtro?Na minha experiência, é fácil de usar.Os exemplos abaixo usam um delegado anônimo, mas você pode definir facilmente seu próprio método ou uma classe para implementar uma classificação ou filtro complexo.Tal classe poderia até ter propriedades para configurar e alterar a classificação e o filtro dinamicamente.

Usar List<T>.Sort(Comparison<T> comparison) com sua função de comparação personalizada:

// 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);
};

Uma abordagem semelhante para obter uma subcoleção de itens da lista.

Usar List<T>.FindAll(Predicate<T> match) com sua função de filtro personalizada:

// 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);
}

O método de "força bruta" que você mencionou é na verdade a solução ideal.Lembre-se, todos os objetos estão na RAM, não há gargalos de E/S, então você pode classificar e filtrar milhões de objetos em menos de um segundo em qualquer computador moderno.

A maneira mais elegante de trabalhar com coleções é o namespace System.Linq no .NET 3.5

Obrigado - também considerei o LINQ para os objetos, mas minha preocupação há perda de flexibilidade para modelos de dados digitados, que eu preciso exibir os objetos na minha lista.

Se você não pode prever neste momento como as pessoas irão classificar e filtrar sua coleção de objetos, então você deve olhar para System.Linq.Expressions namespace para construir suas expressões lambda sob demanda durante o tempo de execução (primeiro você permite que o usuário construa a expressão, depois compile, execute e, no final, use o namespace de reflexão para enumerar os resultados).É mais complicado entender isso, mas é um recurso inestimável, provavelmente (para mim definitivamente) um recurso ainda mais inovador do que o próprio LINQ.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top