I've been working on a high-performance tree view that's actually based on a ListBox. To achieve this, we first start with a hierarchical model where each item implements an IParent interface that exposes an enumerable Children property.
We then 'flatten' that hierarchy into a list-based ViewModel, adding a 'depth' property to each item. We then use that list as the ItemsSource of the ListBox, using the new depth property to indent the ContentPresenter in our custom ListBoxItem template. It all works like a champ and allows us to display several thousand nodes, something a normal TreeView would choke on. It does this because again, it's just a list now and a ListBox easily virtualizes its containers by default whereas a TreeView notoriously struggles with virtualization.
Consider this example hierarchy:
Parent1
Parent2
Child2a
Grandchild2a1
Grandchild2a2
Child2b
Parent3
Child3a
After flattening, it becomes this...
Parent1, Level 0
Parent2, Level 0
Child2a, Level 1
Grandchild2a1, Level 2
Grandchild2a2, Level 2
Child2b, Level 1
Parent3, Level 0
Child3a, Level 1
Currently, I'm doing all this flattening external to the control, but it occurred to me if I instead created a HierarchicalItemsControl, it could do that flattening internally, meaning I could use it for any hierarchical model data that implemented IParent (or even if it didn't, via a GetChildren delegate.)
The issue I'm running into with that approach is in a normal ItemsControl, there is a one-to-one relationship between the items in the Items/ItemsSource properties and the created containers that are arranged on the ItemsPanel. In this case, there is a one-to-many relationship.
Simple, I thought... add HierarchicalItems/HierarchicalItemsSource properties, then internally set the regular Items/ItemsSource properties after flattening. That would maintain the one-to-one relationship.
The problem there is the Items/ItemsSource properties are read/write, meaning people could directly manipulate them and that would break the internal logic of my control.
I'm starting to think I can't use an ItemsControl subclass and will instead have to create my own HierarchicalItemsControl base class, reimplementing most of the internals of ItemsControl manually, but I'm hoping there's another way.
In Summary...
The main problem I'm trying to solve is a way for this specialized HierarchicalItemsControl to create several containers per given item as opposed to the one-to-one of a normal ItemsControl.
Internally it would ultimately be one-to-one with the flattened list, but externally, I don't want people to be able to manipulate that flattened list (i.e. I wanted to lock-down Items/ItemsSource to be read-only, but I don't think you can do that since they are registered DependencyProperties, not simple CLR properties and AFAIK, you can't change a registered DependencyProperty's accessibility.)
