Struggling with showing nested relationship in my TreeView
. Here is the scenario:
In the database I have Category
and Account
tables. Each category can have zero or more sub-categories so this table has a nested relationship with itself. Each category/sub-category can have zero or more Account in it, there is a one-to-many relation between Category
and Account
. Simple, isn't it!
On top of my DB, I have EDMX, with Categories
and Accounts
entities in it and their associations as I mentioned above. For ease of understanding, I have renamed navigation properties so that Categories
now has ParentCategory
, ChildCategories
and Accounts
properties in it.
On top of EDMX, I have my ViewModel, which defines a public property named AllCategories
. My TreeView will bind to this property. I initialize this property at the startup like this:
using (MyEntities context = new MyEntities())
Categories = context.Categories.Include(x => x.Accounts).ToList();
Finally I use the following HierarchicalDataTemplate
to show this stuff:
<HierarchicalDataTemplate DataType = "{x:Type local:Category}" ItemsSource = "{Binding Path=ChildCategories}">
<TreeViewItem Header="{Binding Name}" ItemsSource="{Binding Accounts}" />
</HierarchicalDataTemplate>
<DataTemplate DataType = "{x:Type local:Account}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
This runs fine and shows categories, sub-categories and accounts in the tree, but the problem is that sub-categories show up not only under their parent category, but also at the root-level. This happens for categories of all depths. What am I doing wrong here?
Note: If I add .Where(x=>!x.ParentID.HasValue)
in the VM, it shows only the root category and its immediate children, nothing else.
Edit
Here's what it currently looks like. Everything goes fine up to the dotted white line (I added that line manually for illustration; has nothing to do with WPF). After that, the sub-categories start repeating with their child sub-categories. This process continues over and over till the leaf sub-categories. I believe I understand what's going on here, but don't have a solution for it. For reference, this guy presents a solution of the problem, but he is using DataSets, whereas I'm working with EF and can't translate his solution into my scenario.
The idea is to connect your business data by ObservableCollections and leave your Hierarchical templates simple, so that the treeview won't show duplicate entries. The sample code shows nested viewmodel relationship and the corresponding hierarchical templates. For simplification, the Root is an ObservableCollection (otherwise you would need to add INotifyPropertyChanged here and selective ItemsSource Binding in the TreeView)