How to use Html.TreeViewFor?

Jul 28, 2011 at 5:49 AM

HTML:

@model DemoUI.Models.LocationTree

@Html.TreeViewFor(
            m => m.ChildrenList,
            i => "items",
            ExternalContainerType.span,
            null,
            new object[]
            {
                _S.L<DemoUI.Models.TreeNode>(h => h.DisplayFor(m => m.Name).ToString())
            },
            (x, y) => 0,
            null,
            null,
            null,
            TreeViewMode.Display,
            null,
            (x, y) => TreeViewItemStatus.Hide,
            null
        )

 

Model:

public class LocationTree
    {
        public IList<TreeNode> ChildrenList{set;get;}
    }

    public class TreeNode
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public List<TreeNode> children { get; set; }
        public TreeNode(string value,string name)
        {
            Code = value;
            Name = name;
            children = new List<TreeNode>();
        }
    }

The Code which I use like above, I don't know why show error it run?

Coordinator
Jul 28, 2011 at 9:58 PM

I see just one error:

You invoked th tree on a collections of items:  m => m.ChildrenList!

You have to invoke it on a single node, that will be the root node, that must be an instance of your TreeNode class. In other terms your  LocationTree ViewModel must contain a property of type TreeNode instead of a property of type  IList<TreeNode> ChildrenList.

Moreover, the second argument   i => "items" make no sense. It must return the name of the collection that contains the children of each node. In your case: i => "children";

 

Let me know, if with these changes it works!

If you need to use it in edit model please, don't forget, that when the Tree is used in edit mode, for security reason your TreeNode must implement ISafeCreation, that is you must write:

 public class TreeNode: ISafeCreation
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public List<TreeNode> children { get; set; }
        public TreeNode(string value,string name)
        {
            Code = value;
            Name = name;
            children = new List<TreeNode>();
        }
    }

If you use it just in display mode YOU DON'T NEED TO DO THIS!

Jul 29, 2011 at 4:19 AM

Dear sir, Thanks to your reply very much. I modify my code with your suggest, but it also run error.

@Html.TreeViewFor(
            m => m.RootNode,
            i => "Children",
            ExternalContainerType.span,
            null,
            new object[]
            {
                _S.L<DemoUI.Models.TreeNode>(h => h.DisplayFor(m => m.Name).ToString())
            },
            (x, y) => 0,
            null,
            null,
            null,
            TreeViewMode.Display,
            null,
            (x, y) => TreeViewItemStatus.Hide,
            null
        )
public class LocationTree
    {
        public TreeNode RootNode{set;get;}
    }
    public class TreeNode
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public List<TreeNode> Children { get; set; }
        public TreeNode(string value,string name)
        {
            Code = value;
            Name = name;
            Children = new List<TreeNode>();
        }
    }

Coordinator
Jul 29, 2011 at 4:26 PM
Edited Jul 29, 2011 at 9:59 PM

I tried an example similar to yours (practically equal) and it works for me, Maybe you forgot to add some js file or the css file of the treeview. Verify if all of this references are provided:  jquery.treeview.css ,  jquery.treeview.all.js (orjquery.treeview.all.min.js) .You have to include also the MvcControlsToolkit.Controls-1.2.js file.

 

If this doesn't resolve I need mre infors about the error:

1) javascript error or .Net error?

2) error message

3)When do you receive the message, immediately after you enter the page? after a post?.....

Jun 9, 2012 at 7:39 AM
Edited Jun 9, 2012 at 7:40 AM

Hi Team,

I got compile error as below while I just copy previous code.

 Code:

@Html.TreeViewFor(
            m => m.RootNode,
            i => "Children",
            ExternalContainerType.span,
            null,
            new object[]
            {
                _S.L<DemoUI.Models.TreeNode>(h => h.DisplayFor(m => m.Name).ToString())
            },
            (x, y) => 0,
            null,
            null,
            null,
            TreeViewMode.Display,
            null,
            (x, y) => TreeViewItemStatus.Hide,
            null
        )

 Error:

Error 1 The type arguments for method 'MVCControlsToolkit.Controls.TreeViewHelpers.TreeViewFor<VM,TItem>(System.Web.Mvc.HtmlHelper<VM>, System.Linq.Expressions.Expression<System.Func<VM,System.Collections.Generic.List<TItem>>>, System.Func<int,string>, MVCControlsToolkit.Controls.ExternalContainerType, string, object[], System.Func<object,int,int>, string, object[], System.Func<object,int,int>, MVCControlsToolkit.Controls.TreeViewMode, System.Func<int,string>, System.Func<object,int,MVCControlsToolkit.Controls.TreeViewItemStatus>, MVCControlsToolkit.Controls.TreeViewOptions)' cannot be inferred from the usage. Try specifying the type arguments explicitly. c:\Walter\Dev\MvcLoan\MvcLoan\Views\Tree\Index.cshtml 9 2 MvcLoan

 

Coordinator
Jun 9, 2012 at 9:13 AM

m => m.RootNode that is the root of the tree MUST NOT BE a single node but a list of nodes. That is the TreeViewHelper assumes that in general there are several roots. This design choice was done to avoid a single dummy node in sevral applications (think for instance to a menu implented with the tree.. the first level of the menu contains several items...not just one)

Another source of errors that a lot of peaple do is they forget that all Tree Node must implement the interface ISafeCreation...no need to impement any member, just add this interface to your class definition. It declares that the class can be safely created ...This is done to avoid a malicious user might force the creation of some dangerous type by injecting the client side code that forced the treeview to add a node of that type. When the Tree is built back on post, before creating a node the system verifies the associate type implements this interface. 

Jun 9, 2012 at 10:06 AM
Edited Jun 9, 2012 at 10:27 AM

Hi Team,

Thanks for your quick response.

I use below code, and compile fine, but got an issue when run it.

Model:



 public class TreeViewModels
    {
        public List<EmailElement> EmailFolders { get; set; }
    }



  public class EmailElement : ISafeCreation
    {
        [Required, Format(NullDisplayText = "empty name")]
        public string Name { get; set; }

    }
    public class EmailDocument : EmailElement
    {
        public string Content { get; set; }
    }
    public class EmailFolder : EmailElement
    {
       public List<EmailElement> Children { get; set; }
    }

View:

@using MvcLoan.Models
@model TreeViewModels


@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<div>   
            
            @Html.TreeViewFor(
                    @model => @model.EmailFolders,
                    i => i == 0 ? "Children" : null,
                    ExternalContainerType.span,
                    "filetree treeview-red",
                    new object[] 
                    {
                        _S.L<EmailFolder>(h => 
                            "<span class='folder'>" +h.DisplayFor(m => m.Name).ToString()+"</span>"),
                            
                        _S.L<EmailDocument>(h => 
                            "<span class='file'>" +h.DisplayFor(m => m.Name).ToString()+"</span>") 
                    },
                    (x, y) => x is EmailFolder ? 0 : 1,
                    "filetree treeview-red",
                    null,
                    (x, y) => x is EmailFolder ? 0 : 1,
                    TreeViewMode.InitializeDisplay,
                    (x) => "allnodes",
                    (x, y) => TreeViewItemStatus.initializeShow)
                    
            </div>
       

Error:
Microsoft JScript runtime error: Object doesn't support this property or method
           <script language='javascript' type='text/javascript'>
                $('#EmailFolders___flattened_ItemsContainer').treeview({
                    animated: 1,
                    unique: false,
                    
                    toggle: function() {
   	                    MvcControlsToolkit_TreeViewToggle(this);
                    }
                });
            </script>
 
Coordinator
Jun 9, 2012 at 11:16 AM

Probably you forgot to include the js file that contains all javascript needed for the treeview to work:   jquery.treeview.all-x.x.x.min.js(xxx is the version you are using).

You need also a css file: jquery.treeview.css. Everything is included in the distribution. Do not forget to include also the basic js file needed for the whole mvc controls toolkit to work: MVCControlToolkit.Controls-x.x.x.min.js or  MVCControlToolkit.Controls.Core-x.x.x.min.js.

For the differences among the two above files see here

Anyway I strongli recommed to read the documentation here: The treeview is a quite complex control with a lot of options!

Jun 9, 2012 at 11:38 AM

Great, It works.

Jun 19, 2012 at 9:18 AM
Edited Jun 19, 2012 at 9:19 AM

I'm having problem with defining the parameters for the treeview in view. My controller passes the recursive list (of the type TreeNod) to the view. My model looks like this:

 

public class TreeNod:ISafeCreation
        {
            public TreeNod()
            {                
                child = new List();
            }
            public int id { get; set; }
            public string name { get; set; }
            public ICollection child { get; set; }
        }

What does my treeviewfor looks like in the view??