0

I have a view with a viewmodel as it's DataContext. In the viewmodel I have an ObservableCollection of objects:

AvailableCategories = new ObservableCollection<Category>();

I can bind an ListView to this ObservableCollection without any trouble like this:

ItemsSource="{Binding Path=AvailableCategories}"

I now have the requirement to wrap the ObservableCollection in a class (to aid in xml serialization as in here: How to rename XML attribute that generated after serializing List of objects)

The wrapper class looks like this:

    public class CategoryList : ObservableObject
    {
    private ObservableCollection<Category> _categories;
    public ObservableCollection<Category> Categories
    {
            get
            {
                return _categories;
            }
            set
            {
                if (_categories == value)
                {
                    return;
                }
                _categories = value;
                RaisePropertyChanged(()=>Categories);

            }
        }
    }

and it gets created in the VM like this:

        CategoryList cl = new CategoryList();
        cl.Categories = new ObservableCollection<Category>();

How do I now bind to a Collection within a wrapper class in my VM? This doesn't seem to work:

ItemsSource="{Binding cl.Categories}" 

; EDIT: My VM now exposes the CategoryList like this:

    private CategoryList _cl;
    public CategoryList cl 
    {
        get
        {
            return _cl;
        }
        set
        {
            if (value==_cl)
            {
                return;
            }
            _cl = value;
            RaisePropertyChanged(()=>cl);
        }
    }

But still no joy.

Community
  • 1
  • 1
jidl
  • 195
  • 1
  • 2
  • 19
  • Your view model should expose a property of type CategoryList, e.g. `public CategoryList CategoryList { get; }`. Then you would bind to `CategoryList.Categories`. – Clemens Jun 03 '15 at 08:41
  • Look at the **Output Window** for clues. Looks like the data context may not be set, or incorrect. – Mike Eason Jun 03 '15 at 08:49
  • If I don't wrap the class and use a Collection directly it works fine - so I thought it might be to do with the XAML syntax. The output window doesn't throw anything suspicious. – jidl Jun 03 '15 at 08:54
  • Not sure whether i have understood it correctly but your concern is related to serialization. Yes anything which has events cannot be serialized. What you can do override observablecollection like mentioned in link "http://stackoverflow.com/questions/7665994/c-sharp-custom-observable-collection-should-i-use-composition-or-inheritance" and then add method getdata in it to get plain object in the list – Mahesh Malpani Jun 03 '15 at 09:02

1 Answers1

-1

Try subscribing to the cl.PropertyChanged event in your VM, and in the handler call RaisePropertyChanged(()=>cl) again (you can check the e.PropertyName first if you want, to avoid too many calls). If that works, it means your view is not being notified when the collection property changes because you're binding to a subproperty.

If that doesn't work either, you might have to subscribe to the Categories.CollectionChanged, and Raise the cl property change from that handler too... If that works, that means it is the collection items changing (being added or removed) what's not being notified to the view.

But all this can lead to over-complicated code, if you want to make sure all these handlers are correctly added and removed every time the properties are set...

In general, it is ill-advised to create Bindings to subproperties, as it tends to leads to these notification problems.

almulo
  • 4,918
  • 1
  • 20
  • 29
  • Thanks - I'll take a look. If it's ill-advised I'd rather do it a different way but still need to get the serialization done - maybe I'll copy the list out to another object and serialize that. – jidl Jun 03 '15 at 12:40