This project is read-only.

How to pick a display template or class based on the property in a node

Dec 30, 2012 at 3:45 AM

I have a node type property in my node class that would indicate whether it is the leaf node or the intermediate node.

On the leaf nodes, I don't need to have expand/collapse (+/-) show up. I need to change that dynamically. 

Coordinator
Jan 3, 2013 at 12:45 PM

You can declare that a node is a leaf when the tree is rendered as explained  in the documentation: http://mvccontrolstoolkit.codeplex.com/wikipage?title=TreeView

Specifically you can use the :

Func<int, string>  collection

helper argument hat returns the name of the property containing the children. In order to declare that the node is a leaf it is enough to make this function returns null when your leaf property is true. 

This function receives as input the index of the template you are using for the current node being displayed. Thus the only way to achieve this effect is by using two templates one for leaf nodes and the other for the other nodes (this is quite normal, since leaf nodes, normally have a different appearence)

You can pass to the treeview helper two functions that select the template to be used as a function of the current node, and of the nesting level, namely:

Func<object, int, int> itemTemplateSelectorDisplay

and

Func<object, int, int> itemTemplateSelectorEdit

 

The example included in the binary distribution on codeplex  show how to do this: http://mvccontrolstoolkit.codeplex.com/releases

 

Jan 21, 2013 at 1:41 PM

Hi

I am trying to make this work too. I have a working treeview but want to tune the dusplay to show disfferent display templates  based on a proprty value of the EmailDocument object.

I have based a test page on the sample treeview on this site (EmailFolder and EmailDocument) and wish to use a property of the "EmailDocument" object to assign a different display template (I want to show a different text colour for instance) but I cannot find a way to do this.

My EmailDocument now contains a property called "fileType" which has three values (1,2,3) and each should be used to assign a different display template.

What syntax do I need for the lamda function (itemTemplateSelectorDisplay) i.e

(x, y) => x is EmailFolder ? 0 : (x.fileType == 1 ? use template1 : (x.fileType == 2 ? use template2 : use template3))

 

Any help greatly appreciated.

 

 

 

 

 

Coordinator
Jan 23, 2013 at 9:19 AM

All templates are put into an array (see the code examples) so one may refer to them throught their index in this array. So your code becomes:

(x, y) => x is EmailFolder ? 0 : (x.fileType == 1 ? 1 : (x.fileType == 2 ? 2 : 3))

 

That is the template selection function must return the index of the array to be used in the array of all templates.

Jan 25, 2013 at 11:28 AM
Edited Jan 25, 2013 at 11:30 AM

Hi Thanks for responding.

I understand the concept of the templates array but I get an error.

Here is my line to select the template:

 

I have added an int property "ChildrenCount" to the EmailFolder class to return the number of children, so if it = 0 show template 0 and >0 show template 1. However I get the following runtime error:

(x, y) => x is EmailFolder ? (x.ChildrenCount > 0 ? 0 : 1) : 1
error CS1061: 'object' does not contain a definition for 'ChildrenCount' and no extension method 'ChildrenCount' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
What does this error mean?

 

Any guidance on the syntax here would be much appreciated.

Coordinator
Jan 27, 2013 at 4:41 PM
(x, y) => x is EmailFolder ? (x.ChildrenCount > 0 ? 0 : 1) : 1

 

Is just a function. It is usually written with the lambda expression syntax because it is usually very short, but if you are confused bty lamba expression syntax you can define it as a usual function and then pass the function name as a parameter to the tree view helper.

 

About your error...since you test if x is an EMailFolder, this means that x is a superclass of EMailFolder,  so once you have verified that x is actually an EMailFolder instance before accessing the ChildrenCount field that probably is defined in EMailFolder but not in its superclass you have to cast x to an EMailFolder...so the correct code should be:

(x, y) => x is EmailFolder ? ((x as EmailFolder).ChildrenCount > 0 ? 0 : 1) : 1

 

Jan 28, 2013 at 9:48 AM

aha now I understand, yes it was the cast of x that was causing the confusion.

 

Many thanks