Search code examples
wpfwcfobservablecollectionmaster-detail

WPF Observablecollection master detail scenario


any help with this would be great.

I have a model

public class Master
{
   ...
   public Detail[] Details {get; set;}
}

I am populating my view model from a WCF service which returns my collection of Master objects. I have configured the service reference to return observablecollection so I can use it easily in my view model.

My view model then has

public ObservableCollection<Master> Masters {get; set;}
public Master SelectedMaster {get; set;}

In my view I have 2 listboxes - one bound to my Masters property and the other bound to SelectedMaster.Details.

This all works fine apart from when I add try to add a new detail to the SelectedMaster.

The collection of Details in the SelectedMaster is just a list of Details (not an ObservableCollection) which is clearly why.

What options do I have here? I have tried implementing INotifyPropertyChanged but that doesn't seem to work. I could have another ObservableCollection for the Details but that means I have to keep this collection in sync when the SelectedMaster is changed (the SelectedMaster property is bound to the SelectedItem on my first listbox.

Hope this comes across OK. Would really love some feedback. Would be ideal if WCF could just return the collection of details as an observablecollection as it does with the collection of Masters but it doesn't seem to work like that.

Thanks.


Solution

  • I don't know enough WCF to say whether it can be configured to return nested collections as other types than simple arrays, but I'll try to give the WPF perspective.

    There's no magic here, a simple array doesn't implement any kind of change notification; you simply have to wrap it in some kind of view-aware collection such as ObservableCollection.

    Wrap everything up and only interact with the wrapped collections, example:

    public class MasterWrapper
    {
    ...
        public MasterWrapper(Master master)
        {
            this.Details = new ObservableCollection<Detail>();
            this.Master = master;
            foreach (var detail in Master.Details)
                this.Details.Add(detail);
        }
    ...
    
        public static ObservableCollection<MasterWrapper> GetMasters()
        {
            ObservableCollection<MasterWrapper> results = 
                new ObservableCollection<MasterWrapper>();
            List<Master> modelMasters = null; // Populate this from the service.
            foreach (var m in modelMasters)
                results.Add(new MasterWrapper(m));
            return results;
        }