2008-08-14 38 views
6

Entonces, WPF no admite el comportamiento de clasificación o filtrado estándar para las vistas de CompositeCollections, entonces, ¿cuál sería una mejor práctica para resolver este problema?Ordenando una colección compuesta

Existen dos o más colecciones de objetos de diferentes tipos. Desea combinarlos en una única colección clasificable y filtrable (con la implementación manual de ordenar o filtrar).

Uno de los enfoques que he considerado es crear una nueva colección de objetos con solo unas pocas propiedades centrales, incluidas las que me gustaría que ordenara la colección, y una instancia de objeto de cada tipo.

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

Y a continuación, recorrer mis dos colecciones de objetos para construir la nueva colección compuesta. Obviamente, este es un método de fuerza bruta, pero funcionaría. Obtendría todo el comportamiento de clasificación y filtrado de vista predeterminado en mi nueva colección de objetos compuestos, y podría poner una plantilla de datos en él para mostrar mis elementos de lista correctamente dependiendo de qué tipo está realmente almacenado en ese elemento compuesto.

¿Qué sugerencias hay para hacer esto de una manera más elegante?

Respuesta

1

Actualización: He encontrado una solución mucho más elegante:

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

he encontrado que debido a la reflexión, el tipo específico almacenado en Obj1 es resuelto en tiempo de ejecución y el tipo específico de DataTemplate se aplica como se esperaba!

1

El método de "fuerza bruta" que menciona es en realidad la solución ideal. Eso sí, todos los objetos están en la RAM, no hay cuellos de botella de E/S, por lo que puedes ordenar y filtrar millones de objetos en menos de un segundo en cualquier computadora moderna.

La forma más elegante para trabajar con colecciones es System.Linq espacio de nombres de .NET 3,5

Gracias - También consideré LINQ a objetos, pero mi preocupación no es la pérdida de flexibilidad para datos mecanografiados plantillas, que necesito para mostrar los objetos en mi lista.

Si no se puede predecir en este momento cómo la gente va a ordenar y filtrar su colección de objetos, entonces usted debe buscar en System.Linq.Expressions espacio de nombres para construir sus expresiones lambda en la demanda durante el tiempo de ejecución (primera se deje que el usuario cree una expresión, luego compile, ejecute y al final use el espacio de nombre de reflexión para enumerar a través de los resultados). Es más complicado entenderlo, pero es una característica invaluable, probablemente (para mí definitivamente) aún más innovadora que el propio LINQ.

+0

lubos: Gracias - También consideré LINQ para los objetos, pero mi preocupación es la pérdida de flexibilidad para las plantillas de datos tipeados, que necesito para mostrar los objetos en mi lista. –

1

Todavía no estoy muy familiarizado con WPF, pero veo esto como una pregunta sobre la clasificación y el filtrado de las colecciones List<T>.

(EL PLAZO tener que aplicar manualmente especie o filtro)

¿Le reconsiderar la implementación de sus propias funciones de clasificación o de filtro? En mi experiencia, es fácil de usar. Los ejemplos a continuación usan un delegado anónimo pero puede definir fácilmente su propio método o una clase para implementar un tipo complejo o filtro. Dicha clase podría incluso tener propiedades para configurar y cambiar la clasificación y el filtro de forma dinámica.

Uso List<T>.Sort(Comparison<T> comparison) con su aduana función de comparación:

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

Un enfoque similar para conseguir un sub-conjunto de elementos de la lista.

Uso List<T>.FindAll(Predicate<T> match) con su función de filtro personalizado:

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

Brian: Una vez que se crea MyCompositeObject, obtengo la clasificación y el filtrado de forma gratuita como parte de un ICollectionView. La clave del problema es tratar las colecciones de tipos de objetos por separado y tratarlas como una sola colección. Las colecciones compuestas son la respuesta para crear la colección, pero no el filtro de clasificación. –