Let assume we have following self referencing table of people
Each row represents the person and contains self unique identifier, name, last name and the Id of the parent or null if person has no parent.
Now we would like to display the list of persons as a hierarchical tree showing the relationships between each person.
Let create the Person model that will represent one person of our table.
We use Entity Framework Code First which automatically creates for us a key for a Parent “Parent_Id” and manages loading appropriate Parent object for each Person taken from the database.
In WPF we can show a hierarchical data using the TreeView control with associated HierarchicalDataTemplate. HierarchicalDataTemplate represents one node in the graphical hierarchy tree and as a ItemSource it wants the collection of subnode elements of the same type as the main TreeView.
So I we pass to ItemSource of the TreeView the collection of Persons
then the ItemSource of HierarchicalDataTemplate also has to point to the list of Person objects which will be treated as the child nodes of current node.
Lets create database context.
In EF Code First this class is used as an entry point for all database operations. Using People property we can receive the collection of Person objects stored in our table Person. Now we have everything needed to store and load our People objects from database.
Now if we would like to bind a list of person to a TreeView we must face another problem. As you probably noticed our Person model does not contain a reference to its, let it be called, children. Thus as long as such information is needed we can not properly bind the collection of Person to TreeView hierarchy.
We can handle it in few ways. First approach has been proposed by Stefan Cruysberghs and can be found here. It is based on Linq extension named AsHierarchy which parses a collection of entities and creates a hierarchy of following nodes:
where Entity is regular object, in our case Person, ChildNodes contains a collection of all entities which as a parent has Entity object and Depth indicates the depth of node in hierarchy.
To construct a people hierarchy from collection of Person object we type following:
where as a parameters for AsHierarchy we must provide two functions, first should return an Person identifier and second should return particular Person’s parent identifier. I have added a small modification for second parameter to prevent cases when Person does not have a parent.
Such constructed hierarchy we can now easily bind to the TreeView.
As you can see the TreeView is binded to the main collection hierarchy generated by AsHierarchy method and each of HierarchicalDataTemplate binds to the ChildNodes of HierarchyNode<Person> object.
Final hierarchy looks like following.
On Stefan Cruysberghs page we can see how to customize hierarchy view to fit our needs.
Another approach for showing a hierarchical data taken from recursive self referencing table is to modify a model in the way it provides as a ready hierarchical data with roots and its children loaded in proper way.
Lets add a new property Children to out Person model.
Now the magic of the Entity Framework Code First is that it by default automatically detects the collection Children as a end of bidirectional relation to Parent. Moreover it handles loading this collection and each Person object loaded from database will has this collection filled with appropriate objects. No changes to the database schema is made.
Now what we need is just to get the collection of first level root Persons. Then bind it to the tree and bind the Children to the HierarchicalDataTemplate.
Now hierarchy contains a very high parents of the tree.
and the result looks like this.
As we can see this approach gives the same result as the AsHierarchy extension and in my opinion is more simple and readable.
To represent a hierarchical data in ASP.NET MVC we will use most popular jQuery TreeView plugin. More information and the latest version of jQuery TreeView you can find here.
TreeView plugin usage is very simple. All we need is to put our hierarchy as an html list with unique id and apply a special CSS classes to its element.
Then on document loading we must perform an action on this list
and we get following hierarchy.
Drawing the list of elements can be a little bit problematic. But as always, also for that someone has found a solution. Matt Hidinger on his blog has published a solution ASP.NET MVC Recursive TreeView Helper which extend the HtmlHelper with TreeView method. Lets look at its definition.
It takes a collection of hierarchy roots, reference to its children and a function that returns display data for each element.
Lets take a look how does it work in ASP.NET MVC 3.
You can see one action which loads all Person objects from database (ToList() method) and then selects only those who does not has Parent which means the roots of the hierarchy.
Somewhere it the view we place following code
and we get following result
with cool animating expanding.
Now we can customize the Html extension and use some cool features of jQuery TreeView. Also we can mix it with Stefan Cruysberghs Linq extension presented previously and create a Html helper extension method that allows a plain list of objects and automatically resolves the roots and children.