1

We're trying to expose the contents of two child collections as an additional, all-inclusive IEnumerable property. People have suggested using CompositeCollection for this case, but there are two issues:

  1. There doesn't appear to be a read-only variant, but even if there were...
  2. It's not really suitable for a model layer due to its dependence on System.Windows.Data

Instead, my thought is to use a custom IEnumerable implementation. Here's a made-up example showing the concept...

public class Pets : INotifyPropertyChanged {
    public ObservableCollection<string> Dogs { get; } = new ObservableCollection<string>();
    public ObservableCollection<string> Cats { get; } = new ObservableCollection<string>();

    public IEnumerable All{
        get {
            // Cats go first because dogs always follow! ;)
            foreach(var cat in Cats)
                yield return cat;
            foreach(var dog in Dogs)
                yield return dog;
        }
    }
}

While this does enumerate over all children as desired, the problem I see is that All isn't aware of, nor does it notify of changes to Dogs or Cats since it doesn't implement INotifyCollectionChanged or even INotifyPropertyChanged*, making me wonder if this is the right way to go in the first place.

* This would actually be somewhat easy to 'tack on'. Simply subscribe to the INotifyCollectionChanged event on Dogs and Cats and raise a change notification on All when handling any of those events. But that's an all-or-nothing thing which I'm not sure is the right way to go.

My next thought would be to roll my own lightweight version of a CompositeCollection, but I can't help but think that's using an 18-wheeler to go buy milk at the store. But it does seem to have the most promise.

Is there any other way to make the custom IEnumerable properly handle notifications from the internal collections? (I'm also not opposed to abandon making this a model property in the first place and instead do the combination in the UI layer. Whether I do depends on the answers I get here.)

Mark A. Donohoe
  • 23,825
  • 17
  • 116
  • 235

0 Answers0