Treeview

Jun 19, 2012 at 8:38 AM
Edited Jun 19, 2012 at 9:01 AM

I've completed the data binding part.

The controller passes the recursive list to the view but i'm not sure how to pass the parameters to the treeview.

Please help.

My model looks like this:

 

 public class TreeNod:ISafeCreation
        {
            public TreeNod()
            {
                child = new HashSet();
            }
            public int id { get; set; }
            public string name { get; set; }
            public ICollection child { get; set; }
        }
Coordinator
Jun 19, 2012 at 1:07 PM

Parameters depend on what you want to do:

  1. Are all nodes equal, or there are some nodes that can only be leaf nodes (that is they cannot have children)? Like in the case of folders and documents.
  2. What operations you want to do on the treeview? Just to display it? Editing the label of node only? Editing the node lables and moving nodes from one father to another?
  3. What do you want to display ? just the name field?
  4. What is the desired appearence of the tree? Do you need a fiolder/document tree or just a tree with no icons but just a plus or minus to open the branch containing its children?
  5. How must be the tree shown at the beginning? With all branches operned, with all branches closed...or what?
Jun 19, 2012 at 4:40 PM

Thanks for the quick reply.

The nodes are unequal (country with unequal number of cities). I want to add,edit,delete and display the nodes. The nodes need to be displayed by name and when clicked it should return name or preferably id of selected node. The branches can have simple plus or minus sign. Since the tree has huge data, the branches should be collapsed at the beginning.

I've done the binding part. The controller calls the function in the model and passes the list of type treenod as mentioned above. In the view i've used @model IList<TreeNod> .

Thanks in advance.

Regards,

Bijay.

Coordinator
Jun 21, 2012 at 6:57 AM
Edited Jun 21, 2012 at 7:01 AM

So you have 2 kind of nodes Countries and cities, right? Why you passed me just one node type ? The same treeview can contain nodes with different data types...the only requirement id that they implement ISafeCreation...

A country may have children but a city may have not, so the tree is just 2 levels. Is this correct. Do you want to add deleted and edit both countries and cities or just cities? Do you need to move nodes by dragging them with the mouse...for instance a city from a country to another or not?

What you mean by returning the id when the node is clicked? You mean you need a link that will call another action method and pass it the id of the selected node? It will be a normal link or an ajax link?

Please answer this simple questions and I post me the definition of both counry and city class and I will provide some sample code in the week end.

Finally @model IList<TreeNod> is not a good idea....using a list as viewmodel is always a bad Idea....suppose you need to add something else to the page...where do you put this info...? if you use a class as viewmodel you can just add new properties to it...if you use a list...you can't add new information on the page without changig the code of the whole page.

So a better solution is using a class say MyViewModel which has a single property :  IList<TreeNod> Countries.

This way you may add new properties to MyViewModel if needed.

Jun 22, 2012 at 3:54 AM

Hi,

I said one node type because the country has cities whose property is same as that of country. This is the reason i used recursive list. City is like the subcountry of the country. Moreover the city may have streets and again it's property is same as that of the country. The table I'm using here is.

Id,Name,PID

1,China,0          <=parent node

2,Nepal,0         <=parent node

3,Shanghai,1    <=child node of 1

4,Kathmandu,2    <=child node of 2

5,Thamel,4         <=child node of 4

and so on.

And when China is clicked, i need to pass the id 1 to the jquery so that i can pass it to another view. Moving the nodes by dragging might be preety confusing for me right now so i've not thought about that. But I would want to edit both the city and country as well as add,edit and delete the city from the particular country node.

Regards,

Bijay.

Coordinator
Jun 22, 2012 at 4:04 PM

Something like that should work...in each node I just added a DisplayEditFor that shows the name and allows editing if you click on it:

Html.TreeViewFor(
                    m => m.MyRoot, //Viewmodel property containing the root nodes
                    i =>"child", //name of properties containing children as a function of the template index
                    ExternalContainerType.span,
                    null,//display mode related args, we use edit only mode...so not needed
                    null,//display mode related args, we use edit only mode...so not needed
                    null,//display mode related args, we use edit only mode...so not needed
                    "treeToedit", //class added at the root node...maybe usefull to manipulate tree from jQuery
                    new object[] //it has just one template templatre inde 0 
                    {
                        _S.L<TreeNod>(h => string.Format(
                            "<div class='folder' >{0} {1} {2} {3} </div>", 
                            h.TypedEditDisplayFor(m => m.name, simpleClick: true).ToString(),
                            h.TreeViewDeleteButton(Url.Content("~/Content/folder_delete_16.png"), 
                                ManipulationButtonStyle.Image).ToString(), 
                            h.TreeViewAddButton(1, Url.Content("~/Content/document_add_16.png"), 
                                ManipulationButtonStyle.Image).ToString(),
                            h.TreeViewAddButton(0, Url.Content("~/Content/folder_add_16.png"), 
                                ManipulationButtonStyle.Image).ToString()))
                    },
                    (x, y) => 0, //template selection...since we have just one template always returns 0
                    TreeViewMode.Edit, //edit mode 
                    null, //function to add a css class to each node...usefull for moving nodes or for some jquery stuff...we dont use it 
                    (x, y) => TreeViewItemStatus.InitializeHide, //all nodes initially closed..the it will remeber the previous state
                    new TreeViewOptions
                    { 
                        CanMove=false //prevent node moving thta as default is enabled
                    })

I used a lambda expression template as template node...since template is very simple...but you can use also a Razor template to specify the node template...se here to learn about templates.

Jun 28, 2012 at 4:24 AM
Edited Jun 28, 2012 at 5:14 AM

Thanks for the example. I've tried it in my project but not with much success. It's been just about a month since i've started mvc. So i'm preety much a newbie here.

It shows error in _S.L<TreeNod>. Isn't this the class i've mentioned before? And also is MyRoot the list containing only root nodes? Because what i'm trying to implement is the recursive list as the depth of the tree can only be retrieved at runtime.

It would be real help if you have and could post the sample example along with the model and controller for the example like above.

Regards,

Bijay.

Coordinator
Jun 28, 2012 at 9:52 AM

mmm difficult to understand what is happening. Consider...I have not your code, so the code I have written may contain errors...I had no possibility to test it.

It is better you send me a self contained project...and then I write here the call to the treeview...so I can test it. Actually it is quite simple once one enter into the logis of the control and...if one doesnt go into the kind of panic one has when staring a new stuff :) 

Consider the control maybe into two states: edit and display. If you just provide just the arguments for one of the two states it will automatically go into that state...otherwise we have to provide the button to go from one state to another. In your case I provided just the arguments for edit mode...so it always is in edit mode _S.L<TreeNod> enclose the unique node template, since in your case all node display in the same way...sp you provide an array of node templates with just one element....Another important piece is the function that returns the name of the children collection of each node as a function of the index of its template....now since you have just one template....this function return a costant value....The remainder are just options you can play with

You can use the contact form of my blog to send me the project http://www.dotnet-programming.com/

Jun 29, 2012 at 4:05 AM

Hi,

I've attached the project in the msg and sent it through your blog.

Jul 2, 2012 at 4:48 AM

Thank you very much for the example. I made changes to my project accordingly and it works like a charm.

You're superb.

Cheers.

Coordinator
Jul 2, 2012 at 8:51 AM

Unluckly in the 2.1 release of the toolkit all items controls(thus also the treeview) only accepts lists, this might have been a source of yoyr problems...since you used a ICollection. However the next 2.2 release to be published in a couple of days will accept generic IEnumerables