2009-09-23 23 views
53

El hecho de que es un resultado LINQ podría no ser relevante para la pregunta, pero lo estoy mencionando de todos modos, ya que este es el contexto que ha resultado en esta pregunta.Resultado Cast LINQ para ObservableCollection

Ejecuto una consulta LINQ. El resultado es un;

IEnumerable<MyClass> 

Quiero poner el resultado en una ObservableCollection;

ObservableCollection<MyClass> 

¿Cómo hago esto? (sin ejecutar los elementos IEnumerable y copiar a ObservableCollection). Noté que LINQ tiene algunas funciones para ...(), pero no parece ayudarme con este elenco ...

Respuesta

91

sólo tiene que utilizar:

ObservableCollection<Foo> x = new ObservableCollection<Foo>(enumerable); 

que hará el copiado requerido. No hay forma de observar cambios en la consulta en vivo, aunque la idea de un ObservableQuery<T> es interesante (aunque desafiante).

Si desea un método de extensión para hacer esto, es muy sencillo:

public static ObservableCollection<T> ToObservableCollection<T> 
    (this IEnumerable<T> source) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException("source"); 
    } 
    return new ObservableCollection<T>(source); 
} 
+4

¿Alguien ahora cómo lograr esto en Silverlight 3.0, donde solo está disponible el nuevo constructor por defecto de ObservableCollection ()? –

+0

Desafortunadamente, eso no es de mucha utilidad si desea copiar los resultados en un ObservableCollection que ya está envuelto por un ReadOnlyObservableCollection, ya que el ReadOnlyObservableCollection no se puede recuperar a una nueva colección. En este caso, parece que estás atrapado usando un ciclo foreach y copiando los elementos de a uno por vez. – Neutrino

+0

@Neutrino: Yo diría que ese es un problema diferente al presentado en la pregunta. Es un problema válido, simplemente no creo que sea el que tenía el OP. –

10

puede utilizar un ObservableCollectionconstructor para esto:

ObservableCollection<MyClass> obsCol = 
     new ObservableCollection<MyClass>(myIEnumerable); 
13
var linqResults = foos.Where(f => f.Name == "Widget"); 

var observable = new ObservableCollection<Foo>(linqResults); 
0

IEnumerable es sólo la interfaz.

Debería copiar el contenido de IEnumerable en el ObservableCollection. Puede hacer esto pasando su IEnumerable al constructor de ObersvableCollection cuando cree uno nuevo

0

Escribí esta biblioteca hace unos años.

https://github.com/wasabii/OLinq

No hace exactamente lo que es probable que desee, lo hace más. Es un proveedor de consultas de Linq que analiza el árbol de expresiones, se adjunta a las colecciones a las que se hace referencia y expone otra colección que emite eventos cuando se producen cambios.

Faltan algunos operadores Linq. Pero la base de código no es difícil de extender.

+0

También he estado manteniendo paquetes NuGet para ello. https: //www.nuget.org/packages/OLinq/ – wasabi

+0

Quería usar su paquete, pero el ejemplo proporcionado en el archivo léame no funciona, la llamada a 'ToObservableView' después de' Where' es desconocida –

+1

No estoy seguro del README. Parece que alguien lo arruinó en el pasado. .Donde devuelve un IQueryable. Pero el objeto real es una ObservableQuery. Tengo un método .AsObservableQuery() para hacer el reparto. > collection.AsObservableQuery(). Where (i => i> 2) .AsObservableQuery(). ToObservableView() Similar a .AsEnumerable y AsParallelQuery y todos los demás. – wasabi