I have 5 tables in a L2S Classes dbml : Global >> Categories >> Sub-Category >> Item >> Item Data. I want to be able to navigate from the Global table down a tree like structure to get to the items - displaying the title from the Item Data table.
I have an existing control that uses a IHierarchyData / IHierarchicalEnumerable extended collection by iterating over the collection to output an un-ordered list which I then turn into a tree with jquery. I did it based on Return Un-Ordered List from hierarchical sql data
Is there an easy generic way that I could use to put the data from the above table structure into a a Hierarchical structure so that I could re-use my existing control and and just pass in a different collection.
Have you tried Nested Listviews? I have implemented this solution in several pages. I use ObjectDataSources instead of LinqDataSources directly to keep my data logic separate, but the nested EntitySets work beautifully.
I think what is hanging you up is that you don't need four tables to do this.
Look at Return unordered list from hierarchical sql data again. There aren't four tables there. There's only one.
You can use the Union operator to mash your four tables together.
http://weblogs.asp.net/zeeshanhirani/archive/2008/04/11/union-operator-part-12.aspx
Since you are dealing different types in this case, you will have to implement a common interface on each of them to make the code generic. The basic approach would be to create an interface that includes any needed properties (e.g. DisplayText, ActionURL, etc) then iterate over the collection recursively.
Here's a rough example:
public interface IDataItem
{
string DisplayText { get; }
string ActionUrl { get; }
bool HasChildren { get; }
IEnumerable<IDataItem> GetChildren();
}
public void CreateTree(HtmlTextWriter writer, IEnumerable<IDataItem> collection)
{
writer.WriteFullBeginTag("ul");
foreach (var data in collection)
{
writer.WriteFullBeginTag("li");
writer.WriteBeginTag("a");
writer.WriteAttribute("href",data.ActionUrl);
writer.Write(HtmlTextWriter.TagRightChar);
writer.Write(data.DisplayText);
writer.WriteEndTag("a");
if(data.HasChildren)
CreateTree(writer, data.GetChildren());
writer.WriteEndTag("li");
}
writer.WriteEndTag("ul");
}
You will have to implement the interface on each of your types that you want included in the treeview. The just pass in the collection of the top level type and the method above will walk down the hierarchy creating the needed nested list.