This is a migrated thread and some comments may be shown as answers.

[Solved] Binding TreeView to a Collection of TreeViewItems

2 Answers 271 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Matthew Ruston
Top achievements
Rank 1
Matthew Ruston asked on 06 Apr 2011, 05:33 PM
I'm playing around with the TreeView control and I am wondering if it is possible to bind the TreeView to a pre-built collection of TreeViewNodes. I'm experimenting with an implementation where TreeViewItems are created in my Controller class and passed into my Views via the asp.net mvc Model object.

What I have is simply something like this
@model IEnumerable<TreeViewItem>
@Html.Telerik().TreeView().Name("MyTreeView").???What next???

I was hoping that the TreeView api would support a data binding operation such as
@Html.Telerik().TreeView().Name("MyTreeView").Items(Model)

2 Answers, 1 is accepted

Sort by
0
Accepted
Bob
Top achievements
Rank 1
answered on 31 May 2011, 09:57 PM

I have searched over and over and gone through the source code looking for a solution to this exact problem, but no luck. I came across your post and wish someone would have answered it already, but they didn't so here is my solution.

I am perplexed about the whole SiteMap binding is provided. In all my years of coding web apps (not web sites), I've never, ever used a site map. All the trees displayed in my apps (thousands of variations) have some sort of hierarchy representing some domain object taxonomy - managers / employees, systems / sub-systems / equipment / components, chart of accounts, organization charts, etc..., Now I have exactly the data I need, in the exact format it is needed, but I can't use it.

As I said, I have a IList<Telerik.Web.Mvc.UI.TreeViewItem> object with a full hierarchy of data loaded up from a database. I load the data directly into a list of TreeViewItems because I don't need a domain object graph with ORM and all the associated nonsense for displaying the tree. Each node in the list has various depths of data assigned to the child TreeViewList items in it.

The main problem I have is that when it comes to "Fluent" interfaces I have to admit I am quite tongue-tied. In this case I yearned for the ability to code a simple recursive foreach loop to walk my object graph and add all the data to the tree. But finally, after staring at and re-reading the help file on TreeView databinding for a while I was able to figure out what to do. It turns out that the code to "Bind" this IList<Telerik.Web.Mvc.UI.TreeViewItem> object to the TreeView (in the view) turned out extremely simple:

Controller:

public ActionResult TreeTest()
{
    TreeBuilder builder = new TreeBuilder();
      
    //Build the tree directly from the database into the tree structure
    IList<TreeViewItem> tree = builder.GetTestTree3();
      
    //Store in ViewData
    ViewData["tree"] = tree;
    return View();
}

View:

    <%
        IList<Telerik.Web.Mvc.UI.TreeViewItem> data = ViewData["tree"] as IList<Telerik.Web.Mvc.UI.TreeViewItem>;
          
        Html.Telerik().TreeView().Name("PdMTree").BindTo(data, mappings =>
          {
             mappings.For<Telerik.Web.Mvc.UI.TreeViewItem>(binding => binding
               .ItemDataBound((item, myItem) =>
                 {
                   item.Text = myItem.Text;
                   if (!String.IsNullOrEmpty(myItem.Value))
                     item.Value = myItem.Value;
                   if (!String.IsNullOrEmpty(myItem.Url))
                     item.Url = myItem.Url;
                   item.Checkable = myItem.Checkable;
                     item.Expanded = myItem.Expanded;
                   item.LoadOnDemand = myItem.LoadOnDemand;
                   item.Visible = myItem.Visible;
                 })
               .Children(myItem => myItem.Items));
             }).Render();
           });
%>

Basically I am mapping a  back into a Telerik.Web.Mvc.UI.TreeViewItem. Note that one cannot blindly assign TreeViewItem.Value to TreeViewItem.Value as Telerik has "guard code" in every property assignment that prevents setting a null or empty value (you can leave it null or empty though). I guess somewhere this is beneficial, but right now it turns out to be a pain in the neck that you have to work around (i.e. guard the guard code) for each and every string property you copy.

Also, in case you are wondering, you can't just write item = myItem; or you will get blank and empty items in the tree. Nor can you call MemberwiseClone() as it is a protected method. I didn't need any of the the other properties so I didn't copy them (ActionName, ControllerName, ImageUrl, etc...). Perhaps you could write an extension method and provide a shallow copy constructor for TreeViewItem that would copy the "myItem" instance to the "item" instance, not sure if the whole fluent / builder thing would choke on it though.

But, given all this, our question still stands valid - Why there is no .BindTo(IList<Telerik.Web.Mvc.UI.TreeViewItem>) override for the TreeView? I am equally baffled (Hint to Telerik).

0
Matthew Ruston
Top achievements
Rank 1
answered on 01 Jun 2011, 02:21 PM
Awesome solution. Thanks.
Tags
TreeView
Asked by
Matthew Ruston
Top achievements
Rank 1
Answers by
Bob
Top achievements
Rank 1
Matthew Ruston
Top achievements
Rank 1
Share this question
or