Click here to Skip to main content
Click here to Skip to main content

Building Trees from Lists in .NET

By , 1 Mar 2008
 

Who Is This Article For?

This article is aimed at .NET developers who need to build a tree (or forest) of objects by loading an array or list of rows from a database, and converting them to a tree structure in memory to use or display.

Introduction

Storing hierarchical data in a database is a very common requirement, whether it be product categories, sports tournaments, or staff hierarchies. Over the years, I have had to create, store in a database and display trees many times, and my method has evolved from having fixed-size hierarchies, to abstract classes providing tree functionality, and finally to the method described in this article. This article describes a very simple way to load data from a table, and convert it into a tree in C# code for .NET 2.0+.

While other articles have been written on the subject, the following goals are not always met:

  • You should not need to extend an abstract class, because your data class may already extend another class
  • You shouldn't need to convert your class to be a partial class
  • You shouldn't need to change your database table: as long as it uses the standard parent ID column referring to its own primary key, it should work
  • There shouldn't need to be any type-casting of parent or child objects
  • It should be easy to use

The answer is to define an interface - in this case called ITreeNode - and then have a utility method to build a tree from that. This article assumes that you have a class defined to hold a single node (e.g. a Category object), and that when you get a list of nodes from the database each reference to a parent has been instantiated as an object with its ID set, but without a reference to the fully populated parent object, nor its children.

An Example

Let's look at the very common "Category" entity, used to categorise products. The database table looks like the following:

Table definition of a Category

Let's assume that there are just 8 rows in the database, which break the products into two main categories - "Hardware" and "Software" - and then further sub-categories. In this case "Operating Systems" and "Developer Tools" come under "Software"; "Monitors" and "Peripherals" under "Hardware", and finally "Keyboards" and "Mice" under "Peripherals", giving the following category hierarchy:

Example category hierarchy

In the database, the rows are as follows:

Category table rows

In order to display this information on a website, you create a "Category" class:

public class Category
{
    private int _id;
    private string _name;
    private Category _parent;
    private List<Category> _children;
    
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public Category Parent
    {
        get { return _parent; }
        set { _parent = value; }
    }

    public List<Category> Children
    {
        get { return _children; }
        set { _children = value; }
    }
}

A method is also needed to retrieve all the categories from the database. This will be a "flat" list of each category, i.e. the _parent field will point to an object which only has its ID populated, and _children will be null. A possible example of this method is shown here:

static List<Category> GetListFromDatabase(DbConnection con) {
    DbCommand cmd = con.CreateCommand();
    cmd.CommandText = "SELECT Id, Name, ParentID FROM Category";
    cmd.CommandType = CommandType.Text;
    DbDataReader reader = cmd.ExecuteReader();
    List<Category> categories = new List<Category>(); 
    foreach (DbDataRecord row in reader) {
        Category c = new Category();
        c.Id = (int)row["Id"];
        c.Name = (string)row["Name"];
        if (row["ParentID"] != DBNull.Value)
        {
            c.Parent = new Category();
            c.Parent.Id = (int)row["ParentID"];
        }
        categories.Add(c);
    }
    reader.Close();
    return categories;
}

Once having a list of objects in memory, the ITreeNode interface comes in handy. The first step is to implement this interface:

public class Category : ITreeNode<Category> {
// contents of class remain as above, because the 
// interface is implemented by the Id, Parent, and 
// Children properties
}

The interface requires that we have one property referring to the parent of the category (where null represents a root-level node), and an IList pointing to the children.

Now we can call the TreeHelper utility methods to convert the flat array returned from GetListFromDatabase into a fully populated hierarchy:

IList<Category> topLevelCategories = 
    TreeHelper.ConvertToForest(GetListFromDatabase());

The variable topLevelCategories contains two Categories: "Software" and "Hardware".

Printing Out All Nodes using Nested HTML <ul> and <li> Tags

Using a recursive method, you can easily print out, for example, the full category hierarchy in nested <ul> tags, as follows:

void Page_Load(object sender, EventArgs e) {
    IList<Category> topLevelCategories = 
        TreeHelper.ConvertToForest(Category.GetListFromDatabase());
    Response.Write("<ul>");
    foreach(Category topLevelCategory in topLevelCategories) {
        RenderCategory(topLevelCategory);
    }
    Response.Write("</ul>");
}

void RenderCategory(Category category) {
    Response.Write("<li>" + category.Name);
    if (category.Children.Count > 0) {
        Response.Write("<ul>");
        foreach(Category child in category.Children) {
            RenderCategory(child);
        }
        Response.Write("</ul>");
    }
    Response.Write("</li>");
}

This will render the following output:

  • Software
    • Operating Systems
    • Developer Tools
  • Hardware
    • Monitors
    • Peripherals
      • Keyboards
      • Mice

Searching For a Single Category in the Tree

// in a website, this may use the ASP.NET Cache object.
List<Category> categories = GetCategories();
int categoryId = int.Parse(Request.Params["categoryId"]); 
Category currentCategory = 
    TreeHelper.FindTreeNode(categories, categoryId);

Printing Breadcrumbs

Continuing the example above, this is how the bread crumbs for the current category could be printed:

Category currentCategory = GetCategory();
foreach(Category category in 
    TreeHelper.Iterators.FromRootToNode(currentCategory))
{
    Response.Write(" / " + category.Name);
}

If the current category was "Keyboards", this would render the following HTML:

/ Hardware / Peripherals / Keyboards

Tree Helper

The TreeHelper utility class contains numerous other useful methods - such as GetDepth and HasHierarchyLoop - and iterators - such as DepthFirstTraversal, BreadthFirstTraversal, ClimbToRoot, FromRootToNode, and Siblings.

Check out the fully-documented source code for the full details.

Using Extension Methods and "LINQ to Trees"

If you are using a .NET 3.5 solution, you are able to take advantage of extension methods. This has the effect of implementing methods in interface declarations (which is not possible in older versions of C#), which is probably the most useful aspect of extension methods, and indeed was the reason they were invented.

An example using extension methods:

List<Category> categories = GetCategories().ConvertToForest();
Category current = categories.FindCategory(3);
foreach(Category descendent in current.DepthFirstTraversal()) {
    Response.Write("Depth of " + descendent.Name + ": " + descendent.GetDepth();
}

Remember, ConvertToForest, FindCategory, DepthFirstTraversal and GetDepth are not implemented by the Category class, it simply "inherits" these methods from the TreeHelper class, simply by implementing ITreeNode<T>.

Extension methods go hand-in-hand with LINQ. Yes, strictly speaking, this is simply "LINQ to Objects" rather than "LINQ to trees", but regardless, it is a new way to query your trees:

List<Category> categoryList = Category.GetCategories();

// Get all categories which are not top level categories, 
// and retrieve only the name.
var nonRootCategories = 
    from c in categoryList.DepthFirstTraversalOfList()
    where c.Parent != null
    select new { Name = c.Name };

// Get all categories at Depth 2, ordered by name, and
// get the whole category object.
var level2Categories = 
    from c in categoryList.DepthFirstTraversalOfList()
    where c.GetDepth() == 2
    orderby c.Name ascending
    select c;

Some Cool Stuff

The following .NET language features have made this class much more useful:

  • Interfaces using Generic parameters. Note that the interface definition is ITreeNode<T>, and the reference to the parent, for example, is T Parent. This means you never need to cast from ITreeNode to your class.
  • Creating iterators using the "yield" keyword. This is perhaps one of the more under-rated features introduced in .NET 2.0 which makes creating Iterators so easy. Check out the methods in the TreeHelper<T>.Iterators class.
  • Extension methods and LINQ. Querying trees with LINQ can certainly make certain tasks much easier... and fun.

History

  • 27th February, 2008: Initial release
  • 2nd March 2008: Changed TreeHelper from a generic class to non-generic class with generic methods (to allow type method inference), and added the section on LINQ.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Daniel Flower
Software Developer
China China
Member
Daniel has a Bachelor of Science with First Class Honours from the University of Auckland, and has designed and developed software in companies large and small.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionExpose your Tree Structure as WCF Data ContractmemberMember 954892528 Oct '12 - 22:05 
Hi,
 
I am failed to use this kind of tree structure as a WCF data contract it is giving stackoverflow exception..
 
Have you tried to convert your category class into DataContract. Please help if you succeed.
 
Thanks,
Paumil
QuestionCategory class body after implementation of the ITreeNode interfacememberMember 39308187 Aug '12 - 0:10 
Hello,
 
Thanks for your great share but can you please send me the body of the "Category" class after the implementation of the "ITreeNode" interface. It will be great help for me.
 
Please help me because I searched a lot on google but your article is the best one from them and fulfil my all requirements.
 
my email id is "haider.programmer@gmail.com"
 
Thanks,
Haider
AnswerRe: Category class body after implementation of the ITreeNode interfacememberDaniel Flower10 Aug '12 - 20:13 
Hi there, I wrote this years ago so I'm not sure if this is the best version, but I've found this code on my computer:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using System.Data.Common;
using Library;
 
public class Category : ITreeNode<Category>
{
	private int _id;
	private string _name;
	private Category _parent;
	private IList<Category> _children;
	
	public int Id
	{
		get { return _id; }
		set { _id = value; }
	}
 
	public string Name
	{
		get { return _name; }
		set { _name = value; }
	}
 
	public Category Parent
	{
		get { return _parent; }
		set { _parent = value; }
	}
 
	public IList<Category> Children
	{
		get { return _children; }
		set { _children = value; }
	}
 
	public override bool Equals(object other) {
		Category otherCategory = other as Category;
		if (otherCategory == null) return false;
		return _id == otherCategory._id;
	}
 
	public override int GetHashCode()
	{
		return _id;
	}
 

	public static List<Category> GetListFromDatabase(DbConnection connection) {
		DbCommand command = connection.CreateCommand();
		command.CommandText = "SELECT Id, Name, ParentID FROM Category";
		command.CommandType = CommandType.Text;
		DbDataReader reader = command.ExecuteReader();
		List<Category> categories = new List<Category>(); 
		foreach (DbDataRecord row in reader) {
			Category c = new Category();
			c.Id = (int)row["Id"];
			c.Name = (string)row["Name"];
			if (row["ParentID"] != DBNull.Value)
			{
				c.Parent = new Category();
				c.Parent.Id = (int)row["ParentID"];
			}
			categories.Add(c);
		}
		reader.Close();
		return categories;
	}
}
 
Hope that helps.
GeneralHi, Have you tried it with LINQ? How did you solve this part?memberhcoder 190013 Jun '11 - 2:53 
here we have a special case ...where we create parents.
 
How is this done in Linq? Smile | :)
With a simple -> var cats = (from c in db.Categories
select c);
It turns all categories as root.
 
//If ParentID is Null then it's Root Category.
if (dr["ParentID"] != DBNull.Value)
{
 
cat.Parent = new Category();
cat.Parent.Id = (int)dr["ParentID"];
}
GeneralRe: Hi, Have you tried it with LINQ? How did you solve this part?memberhcoder 190013 Jun '11 - 20:23 
I guess this would do :
 
var cats = (from c in db.Categories
orderby c.ParentID
select c);

foreach (Category cat in cats)
{
if (cat.ParentID != null)
{
cat.Parent = new Category();
cat.Parent.Id= cat.ParentID.Value;
}
}
 
return cats.ToList();
QuestionHow to implement ASP.NET TreeView using this utility [modified]memberJoshTheFlame28 Jul '10 - 1:00 
Hi,
 
I have the following code
public partial class MenuManagement : System.Web.UI.Page
{
  TreeNode rootNode = new TreeNode();
  TreeNode childNode = new TreeNode();
 
  public void PopulateTreeView()
  {
   IList<Category> topLevelCategories =  
   TreeHelper.ConvertToForest(Category.GetAllMenusFromDatabase());
 
   foreach (Category topLevelCategory in topLevelCategories)   
   {
     //Adding Root Items
     rootNode.Text = topLevelCategory.Name;
     rootNode.Value = topLevelCategory.Id.ToString();
     TreeView1.Nodes.Add(rootNode);
     
     RenderCategory(topLevelCategory);
   }
  }
 
 void RenderCategory(Category category)
 {
  if(category.Children.Count > 0)
   { 
    foreach( Category child in category.Children)
     {
         childNode.Text = category.Name;
         childNode.Value = category.Id.ToString();
         rootNode.ChildNodes.Add(childNode);
         RenderCategory(child);
     }
   }
  }
}
 
I have one control called TreeView1 on the page and want to add rootNodes and ChildNodes. Can you please guide how to populate treeview with parent and child items. Actually want to know where to place the code to fill Root Nodes and where to put the code for ChildNodes..I am getting index error on rootNode.ChildNodes.Add(childNode) line..Please guide by correcting my code.
 
Thanks

modified on Wednesday, July 28, 2010 7:28 AM

GeneralImplementation helpmemberJoshTheFlame18 May '10 - 21:50 
Dear danial,
 
Your classes are great and exactly what I needed. I am novice in asp.net world so need your help.
 
I've followed your instructions step by step and did the following.
 
1. Created a database and Category table in SQLSERVER 2008.
2. Created a stored procedure to retrieve all nodes
3. Downloaded and Add your class "ITreeNodeDotNet3.cs" in my solution.
4. Created a class file "Category.cs"
 
Here is the code.
------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Common;
using System.Data;
using Microsoft.Practices.EnterpriseLibrary.Data;
using TreeUtility;
 
/// <summary>
/// Summary description for Category
/// </summary>
public class Category
{
private int _id;
private string _name;
private Category _parent;
private List<Category> _children;
 
public int Id
{
get { return _id; }
set { _id = value; }
}
 
public string Name
{
get { return _name; }
set { _name = value; }
}
 
public Category Parent
{
get { return _parent; }
set { _parent = value; }
}
 
public List<Category> Children
{
get { return _children; }
set { _children = value; }
}
 
static List<Category> GetListFromDatabase()
{
 
//Establish database connectivity and fetch the menus from menu_template table
Database db = DatabaseFactory.CreateDatabase();
 
//Create Command object for stored procedure
DbCommand cmd = db.GetStoredProcCommand("sp_Get_MenuNodes");
 
//Read in the IDataReader by executing the stored procedure
IDataReader reader = db.ExecuteReader(cmd);
 
List<Category> categories = new List<Category>();
while (reader.Read())
{
Category c = new Category();
c.Id = (int)reader[0]; //Node ID
c.Name = (string)reader[1]; //Node Name
if (reader[2] != DBNull.Value)
{
c.Parent = new Category();
c.Parent.Id = (int)reader[2];
}
categories.Add(c);
}
reader.Close();
return categories;
}

}

 
Here is my "Default.aspx.cs" file code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using System.Data;
using System.Globalization;
using System.Web.Security;
using System.Data.Common;
using System.Collections;
using System.Threading;
using TreeUtility;
 
public partial class _Default : System.Web.UI.Page
{
public string strHTML;
public class Category : ITreeNode<Category> {
// contents of class remain as above, because the
// interface is implemented by the Id, Parent, and
// Children properties
}
protected void Page_Load(object sender, EventArgs e)
{
IList<Category> topLevelCategories =
TreeHelper.ConvertToForest(Category.GetListFromDatabase());
Category xy = new Category();
Response.Write("<ul>");
foreach (Category topLevelCategory in topLevelCategories)
{
RenderCategory(topLevelCategory);
}
Response.Write("</ul>");
}
 
void RenderCategory(Category category)
{
Response.Write("<li>" + category.Name);
if (category.Children.Count > 0)
{
Response.Write("<ul>");
foreach (Category child in category.Children)
{
RenderCategory(child);
}
Response.Write("</ul>");
}
Response.Write("</li>");
}


 
Problems I am facing
------------------------
1. Even though I've build the Category.cs but still its showing red underline in "Default.aspx.cs" where I called "(Category.GetListFromDatabase());" it cant find GetListFromDatabase()..
 
2. I dont know how to do where you said
Once having a list of objects in memory, the ITreeNode interface comes in handy. The first step is to implement this interface:
 

public class Category : ITreeNode<Category> {
// contents of class remain as above, because the
// interface is implemented by the Id, Parent, and
// Children properties
}

 
I've added the interface code right after Category class but its not working..
 
Please guide I would really appreciate.
GeneralRe: Implementation helpmemberDaniel Flower18 May '10 - 22:45 
Hi Josh,
 
I can see a couple of issues with your code. First of all, delete the following from your Default.aspx.cs class:
public class Category : ITreeNode<Category> {
// contents of class remain as above, because the
// interface is implemented by the Id, Parent, and
// Children properties
}
 
Now, go back to Category.cs and find the following line:
public class Category
 
Change it to:
public class Category : ITreeNode<Category>
 
In other words, you are saying that your class Category implements the ITreeNode interface.
 
As okoji Cyril kindly pointed out in the comments below, you will need to change references to List<Category> to become IList<Category> in the field and property only:
private IList<Category> _children;
And:
public IList<Category> Children
 
This is my fault; I really should fix this.
 
I think after you delete your Category class which is inside your Default.aspx class, you will be able to successfully call Category.GetListFromDatabase()
 

Hope that helps. Good luck!
GeneralRe: Implementation helpmemberJoshTheFlame19 May '10 - 0:02 
Daniel,
 
Thanks zillion times for your corrections. The category.cs file has no errors and the function is now accessible. Also made following corrections

private IList<Category> _children;
And:
public IList<Category> Children

 
I am having problems correcting "ITreeNodeDotNet3.cs" even though followed "okoji cyril" but didnt get him correctly I guess..
 
Here is my code of "ITreeNodeDotNet3.cs".

using System;
using System.Collections.Generic;
 
namespace TreeUtility
{
/// <summary>
/// An object which implements this interface is considered a node in a tree.
/// </summary>
public interface ITreeNode<T>
where T : class
{
 
/// <summary>
/// A unique identifier for the node.
/// </summary>
int Id
{
get;
}
 
/// <summary>
/// The parent of this node, or null if it is the root of the tree.
/// </summary>
T Parent
{
get;
set;
}
 
/// <summary>
/// The children of this node, or an empty list if this is a leaf.
/// </summary>
///
public System.Collections.Generic.IList<Category> Children
{
get { return _children; }
set { _children = value; }
}
 
//IList<T> Children
//{
// get { return _child; }
// set;
// }
 
}
 

 
On compilation its throwing an error "modifier 'public' is not valid for this item d:\dynamicmenu\App_Code\ITreeNodeDotNet3.cs Line 34 Column 59
 
Line 34 is
----------
public System.Collections.Generic.IList&lt;Category&gt; Children
 
I think this is the last problem and after that I will have the implementation of your lovely Tree object.
GeneralRe: Implementation helpmemberDaniel Flower19 May '10 - 0:34 
Hi Josh,
 
You shouldn't need to change ITreeNodeDotNet3.cs
 
That defines the interface and so can't have any implementation (things like return _children; is implementation). The problem okiji pointed out is that the interface (ITreeNode<T>) didn't match the implementation (Category). So, you should still have the following in the ITreeNodeDotNet3 file:
 
IList<T> Children
{
  get;
  set;
}
 

Hope that helps. Once you get it working, you will understand a lot more if you learn about interfaces in C# and also learn about generics. I'm sure there will be lots of good articles here on CodeProject. Good luck!
GeneralRe: Implementation helpmemberJoshTheFlame19 May '10 - 0:49 
Daniel,
 
You are a genius Smile | :) wowwwwwwwwww...it worked like a charm ..I must say it was a learning pleasure and going to dissect your entire classes tonight and will learn from it.
 
Thank you once again for sharing such a master piece.
 
God bless you.
 
Josh
GeneralRe: Implementation helpmemberhcoder 190019 May '10 - 20:04 
It's indeed a master piece Smile | :) Wonderful article!
 
Thumbs Up | :thumbsup:
GeneralWith StringBuilder Rendering ...memberhcoder 190018 May '10 - 18:48 
//you may want to rename CategorName to Name.
//Also, it's ready for Jquery Use here: http://jquery.bassistance.de/treeview/demo/?1.0.0[^]
 
PageLoad()
{
IList<Category> topLevelCategories = TreeHelper.ConvertToForest(CategoryList);
LTreeView.Text = RenderCategories(topLevelCategories);
}
 
public string RenderCategories(IList<Category> topLevelCategories)
{
StringBuilder sb = new StringBuilder();
StringBuilder sbSubCat = new StringBuilder();
sb.Append(@"<ul id=""navigation"" class=""treeview"">");

foreach (Category topLevelCategory in topLevelCategories)
{
sb.Append(RenderSubCategory(topLevelCategory));
 
}

sb.Append("</ul>");
 
return sb.ToString();
}
 

public string RenderSubCategory(Category category)
{
StringBuilder sb = new StringBuilder();
// sb.Append(RenderedSub); //Appending the initial or recursively received HTML.
 
if (category.Parent == null) //Root. Use Jquery to Open Sub.
{
sb.Append("<li>" + @"<span class=""" + "" + @""">" + category.CategoryName + "</span>");
}
else
{
// Response.Write(@"<li class=""expandable""><div class=""hitarea expandable-hitarea ""></div>");
sb.Append(@"<li class=""last"">");
sb.Append(@"<a class = """" href=""" + "?catID=" + category.Id + @""">" + category.CategoryName + " (" + category.ProductsCount + ")" + "</a>");
 
}
if (category.Children.Count > 0)
{
sb.Append(@"<ul style=""display: block;"">");
foreach (Category child in category.Children)
{
sb.Append(RenderSubCategory(child));
}
sb.Append("</ul>");
}
sb.Append("</li>");
 

return sb.ToString();
}
GeneralRe: With StringBuilder Rendering ...memberDaniel Flower18 May '10 - 22:32 
Hi there, thanks for your contribution! Yup, definately a good idea to use a string builder if you need it as a string.
 
Love the jquery use as well - it's great being able to just render simple HTML and then use jquery to bring it to life, isn't it?
GeneralI have a problem, please help!memberMamukaHachidze2 Dec '09 - 12:14 
Doing the:
 
ArmType currentType = ArmTypeBO.Get(arm.ArmTypeId);
foreach (ArmType type in TreeHelper.FromRootToNode(currentType))
{
this.Master.HeaderDescription = (" / " + currentType.Title);
}
 
I got:
 
The children of startNode is null. Have you populated the tree fully by calling TreeHelper<T>.ConvertToForest(IEnumerable<T> flatNodeList)?
Parameter Name (translation from Russian): startNode
 
The Interafce is implemented 100%:
 
/// <summary>
/// Gets or sets the родительский тип/вид (класс) вооружения.
/// </summary>
/// <value>Model.ArmType</value>
public ArmType Parent
{
get;
set;
}
 
/// <summary>
/// Gets or sets the список дочерних типов/видов (классов) вооружения.
/// </summary>
/// <value>Model.ArmType</value>
public IList<ArmType> Children
{
get;
set;
}
GeneralRe: I have a problem, please help!memberDaniel Flower3 Dec '09 - 21:22 
Hi Mamuka,
 
I take it you have called TreeHelper<T>.ConvertToForest(IEnumerable<T> flatNodeList) before using the iterator?
GeneralSome correctionmemberokoji Cyril1 May '09 - 6:54 
1. ITreeNode interface
 
/// <summary>
/// The children of this node, or an empty list if this is a leaf.
/// </summary>
IList<T> Children
{
get;
set;
}

 
while Class Category implemented property Children as List
 
public List<Category> Children
{
get { return _children; }
set { _children = value; }
}
 
the correct impementation should be System.Collections.Generic.IList;
 
public System.Collections.Generic.IList<Category> Children
{
get { return _children; }
set { _children = value; }
}
 
Magic has often been thought of us the art of making dreams come true; the art of realizing visions. Yet before we can bring birth to the vision we have to see it.

GeneralDuplicate Node Names...memberAbbas Mousavi4 Mar '09 - 2:39 
I found your article very useful for creating a famil tree in XMAL (3.5) and managed to prodcue a WPF control that binds to a db table.
 
However, your code throws an eception when a child with the same name are entered under under more than parent. I need to produce a tree view like the one below; but as your code defines a unique ID for each node, it seems it woud not be possible to build this kind of tree.
 
Any thougts?
 
-All School Students
---Student A
---Student B
---Student C
---Student D
 
-Class (1)
---Student A
---Student B
 
-Class (2)
---Student C
---Student D
 
- Football Team
---Student A
---Student D
 
- Cricket Team
---Student A
---Student C
 
Abbas
AnswerRe: Duplicate Node Names...memberDaniel Flower9 Mar '09 - 3:16 
Hi Abbas,
 
For a problem like this, you would need to declare separate classes for students and teams (which makes sense; you can't say a student is a type of cricket team). Make individual Team objects (All Students, Class A, etc), where each team has a list of students, and each student has a list of teams (in the database, there would be a many-to-many relationship with a StudentTeam table or similar).
 
In fact, you may not need to use ITreeNode at all, unless you have hierarchies of teams (e.g. Sports Teams could be the parent of Cricket teams).
 
I hope that helps, good luck.
Questioncast IList&lt;child&gt; to IList&lt;parent&gt; [modified]memberMunazzahNawaz4 Feb '09 - 0:19 
I am facing a very serious issue and trying to find out any work around.
 
I have a function having IList<parentclass> as return type and trying to return IList<child>.

Here is the code:
 
public override IList<parent> Function()
{
 
IList<child> childObject;
 
.
 
.
.
 
.
return childObject;
}
 
I am getting the error that can't cast from child to parent and explicit conversion is required.
and you can't cast a child object to base object explicitly, it gives u a runtime error.
 
modified on Wednesday, February 4, 2009 10:52 PM

AnswerRe: cast IList&lt;child&gt; to IList&lt;parent&gt;memberDaniel Flower9 Mar '09 - 3:12 
Hi there, I'm not sure if you are using the ITreeNode correctly, as parents and children should be of the same type. Good luck!
GeneralProblem with ConvertToForestmemberTonyS24 Oct '08 - 1:05 
I like the concept you have presented here but I am having a slight problem in implementation.
 
I can't get the ConvertToForestMethod working. I keep getting a problem with casting. Using the code you have presented I can't get around the problem.
GeneralRe: Problem with ConvertToForestmemberDaniel Flower6 Nov '08 - 7:00 
Hi, sorry for the delay in replying. If it's not too late, could you expand on the problem, e.g. which line is it happening at? What does your data look like before you send it through ConvertToForest?
 
If you want you can send me some sample code and I'll have a look at it.
 
Thanks.
GeneralRe: Problem with ConvertToForestmemberMehranzand10 Jul '09 - 8:16 
Hi ,
 
I have same problem with ConvertToForset method
 
I got this error :
 
The type 'Category' must be convertible to 'TreeUtility.ITreeNode<Category>' in order to use it as parameter 'T' in the generic type or method 'TreeUtility.TreeHelper.ConvertToForest<T>(System.Collections.Generic.IEnumerable<T>)'
 
thank you
GeneralRe: Problem with ConvertToForestmemberDaniel Flower11 Jul '09 - 6:38 
Hi Mehranzand,
 
Does your Category class implement the ITreeNode<Category> interface?

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 2 Mar 2008
Article Copyright 2008 by Daniel Flower
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid