Lazy or deferred population?

Sep 14, 2010 at 1:20 PM

When implementing a tree view in WPF, I commonly put a dummy, null, entry in the ObservableCollection<T> of children. This causes the tree view to display the [+] expander, and then I handle the expansion event (by binding IsExpanded) by "realizing" the actual content -- i.e. removing the null entry and going to the database/service/whatever.

This means that I've got, in my viewmodel object's constructor.

_children = _model.Children.Where(predicate).Select(m => new TreeNodeViewModel(this, m, predicate));


Obviously, the call to Add throws AccessViolationException, because _children is actually a ReadOnlyContinuousCollection. Is there any way around this? For example, would it be feasible for me to write an extension such that:

_children = _model.Children.Where(predicate).Select(m=>etc).Lazy();

...would work?

Any other suggestions/ideas?

Sep 15, 2010 at 6:03 PM

How about instead of setting _children to a CLinq collection when initializing the object set it to an ObservableCollection with the "null" object. Then when IsExpanded is triggered update your _children to your CLinq query and throw a OnPropertyChanging/OnPropertyChanged for Children so the view rebinds.

Sep 16, 2010 at 2:40 PM

In the end, I did just that:


1. Have a _children field and a Children property (that raises PropertyChanged).

2. Have a static property called LoadingChildren that is an ObservableCollection containing a null.

3. Initially set Children = LoadingChildren.

4. Have a _realChildren field, set to _model.Children.Where(predicate).Select(m => etc).

5. In the handler for set_IsExpanded(true), call _model.RealizeChildren() and set Children = _realChildren.