michael
michael

Reputation: 15302

Is there an easier way to combine multiple observable collections into a single observable collection?

I'm using the CSLA Framework and MVVM Light for my application. For anyone unfamiliar with it, CSLA allows me to construct an object graph and provides observable binding lists, such as the following:

public class RootObject : BusinessBase<Customer>
{
    public FriendList Friends { get { ... } set { ... } }
}

public class FriendList : BusinessListBase<FriendsList, Friend> { }

public class Friend : BusinessBase<Friend>
{
    public AnnouncementList Announcements { get { ... } set { ... } }
}

The problem I have is I want to aggregate all of the Announcements together into a single ObservableCollection<Announcement> for my view model.

public class MainViewModel
{
    private RootObject _graph;

    public MainViewModel(int userId)
    {
        _graph = GetObjectGraph(userId);

        var announcements = _graph.Friends.SelectMany(x => x.Announcements);
        Announcements = new ObservableCollection<Announcement>(announcements);

        // Some way of synchronizing every new collection here!
    }

    public ObservableCollection<Announcement> Announcements { get; private set; }
}

I did have some code which attempted to subscribe to the collectionchanged event of the FriendList and then subsequently subscribe to the collectionchanged event of each new friend and unsubscribing from old friends and etc, but it got extremely complicated extremely fast.

I also tried looking at Reactive Extensions but I have no idea how to get it to remove items as friends are removed or announcements are removed.

I also came across some MVVM framework named ReactiveUI, but I don't want to redo everything out of MVVMLight and into ReactiveUI.

I'm really not sure if there is a better way, perhaps a way to just make Rx work without an entire framework, just for this scenario? I just don't want to have to go back to option one of managing a bunch of collection changed events with nested collection changed event subscriptions!

Upvotes: 1

Views: 1819

Answers (2)

GoJiTa972
GoJiTa972

Reputation: 151

I know that this question is quite old, but it seems to me that Binding multiple ObservableCollections to One ObservableCollection is the answer you're looking for.

Basically, use a the CompositeCollection class that allows to treat multiple collections as a single collection.

Upvotes: 1

Ana Betts
Ana Betts

Reputation: 74702

I also came across some MVVM framework named ReactiveUI, but I don't want to redo everything out of MVVMLight and into ReactiveUI.

You don't have to rewrite anything to use ReactiveUI in your MVVM Light project, everything will work with your existing code.

That being said, while RxUI's Derived Collections support several operations to transform lists, SelectMany isn't one of them (i.e. to take a base list of lists and convert it into a flattened list). You'd have to write this bit yourself, though Rx and ReactiveList will make this task much easier to accomplish than doing it by-hand.

Upvotes: 1

Related Questions