WPF LINQ and the ObservableCollection

21,554

Solution 1

What makes you think you can't use LINQ with ObservableCollection<T>? It implements Collection<T> so it should be fine.

For example:

using System;
using System.Collections.ObjectModel;
using System.Linq;

class Test
{
    static void Main()
    {
        var collection = new ObservableCollection<int>()
        {
            1, 2, 3, 6, 8, 2, 4, 5, 3
        };

        var query = collection.Where(x => x % 2 == 0);
        foreach (int x in query)
        {
            Console.WriteLine(x);
        }
    }
}

Solution 2

Just for anybody else who may come across this issue with trying to filter an ObservableCollection but find that they can't.

Jon is absolutely correct in that there is no reason why you can't do this but the key thing for a newbie or for someone who has been developing with WPF for a while, is that you need to include the "using System.Linq;" namespace. As you soon as you do this, you can do a ".where" query on your object.

Solution 3

The OP asked especially for the LINQ ".ForEach()" Method, which cannot be used on ObservableCollection< T >, since it's implemented for List< T > only.

There is another SO-Topic, where I found my solution: https://stackoverflow.com/a/200584/2408978

Share:
21,554
lamarmora
Author by

lamarmora

Updated on July 05, 2022

Comments

  • lamarmora
    lamarmora almost 2 years

    In my WPF application I'd like to use LINQ as much as possible (especially to avoid foreach). But WPF works a lot with the ObservableCollection, and I can't use LINQ with these kind of collection. What can I do?

  • lamarmora
    lamarmora almost 14 years
    Thank you. Sorry. I remember there were problems with some queries, but now I have tried and everything works.
  • tofutim
    tofutim over 10 years
    The resulting query is an IEnumerable. Is there a clean way of going back into an ObservableCollection<int> ?
  • Jon Skeet
    Jon Skeet over 10 years
    @tofutim: No, not as far as I'm aware I'm afraid.
  • EluciusFTW
    EluciusFTW over 10 years
    Clean way back? What about new ObservableCollection<int>(collection). Almost all (if not all) collection types have constructors accepting an IEnumerable<T> as argument.
  • Jon Skeet
    Jon Skeet over 10 years
    @ToaoG: That takes a copy of the data - it won't change when the original observable collection changes, which is what I'd expected tofutim to require. I could have misunderstood though.
  • EluciusFTW
    EluciusFTW over 10 years
    Maybe this is not the right place for my method, but I do that all the time, e.g., in a method with signature public ObservableCollection<T> DoSomething(ObservableCollection<T> _input) where in the method I use Linq, e.g., var subset = _input.where(n = > n.condition) and then return new ObservableCollection<int>(subset)
  • Jon Skeet
    Jon Skeet over 10 years
    @ToaoG: It depends on what you're trying to observe. Normally I'd expect an observable collection to want to be fairly closely linked to the original source collection. But YMMV.
  • EluciusFTW
    EluciusFTW over 10 years
    Yeah I typed my answer a bit hastily, the proper signature should be public ObservableCollection<T> DoSomething(IEnumerable<T> _input). But what I said happens very naturally if your view displays an ObservableCollection which should be filtered according to some user input - then I use above code in the getter of the bound ObservableCollection. Is there a better way?
  • Jon Skeet
    Jon Skeet over 10 years
    @ToaoG: If you're going to filter it so that you don't actually observe any changes in the original data, what good is it doing you to use ObservableCollection at all? What changes will you observe?
  • EluciusFTW
    EluciusFTW over 10 years
    Say you have a property called data of type List<T> with all the data, and bind a property of type ObservableCollection<T> to your view. As getter get { return new ObservableCollection<T>(data.Where(n => n.name == 'What User entered in a textbox')); }. Then the view will only see the part of the data that the user requests.
  • Jon Skeet
    Jon Skeet over 10 years
    @ToaoG: You didn't answer my question: why bother using an ObservableCollection at all, if you're not going to be able to observe any changes? (Because it's a copy of the data.)
  • derekantrican
    derekantrican over 7 years
    Thanks for the additional answer! That was my issue :)
  • Tormod
    Tormod about 7 years
    The resulting ObservableCollection will not update if the query result update as a consequence of the underlying source being updated.
  • Tormod
    Tormod about 7 years
    @JonSkeet Is a possible solution to wrap every LINQ operator that describes ObservableCollection<T> instead of IEnumerable<T> and forwards a event notification on CollectionChanged. It will trigger everytime the underlying collection changes as opposed to when the query result changes, but that's not unheard of. Are ObservableCollection objects expensive? It's a bit weird that there is no IObservableCollection<T> interface.
  • Jon Skeet
    Jon Skeet about 7 years
    @Tormod: It sounds like you should possibly look at Reactive Extensions, which is more designed around the idea of reacting to changes as a fundamental operation.