Fredrik Normén's Blog - NSQUARED²
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Microsoft Most Valuable Professional
     .Net Framework - ASP.Net - Architecture - Development
NOTE: This list of posts will only list the 15 latest posts, to see the rest, select from the Archives located in the menu to the left. The RSS will only list the 10 lastest posts.
Extend the TreeView's nodes.

Category:  ASP.Net 2.0

In Beta 2 (Will probably work if you have the Feb CTP) you can create your own TreeNode class, and if you override the RenderPreText, you can render HTML before each TreeNodes. If you override the RenderPostText method, you can render HTML after each TreeNodes.

 

The following is a custom TreeNode class that will render a RadioButton before the TreeNode, a CheckBox after the TreeNode and a Style attribute to the TreeNode’s Link (The displayed text), so you can specify different styles for each TreeNode:

 

using System;

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Web.UI;

using System.Web.UI.WebControls;

  

namespace Test

{

    public class MyTreeNode : TreeNode

    {

        private string _nodeStyle;

 

        protected override void RenderPreText(System.Web.UI.HtmlTextWriter writer)

        {

            writer.AddAttribute("type", "radio");

            writer.RenderBeginTag(HtmlTextWriterTag.Input);

            writer.RenderEndTag();

 

            writer.AddAttribute("style", this._nodeStyle);

        }

 

        protected override void RenderPostText(System.Web.UI.HtmlTextWriter writer)

        {

            writer.AddAttribute("type", "checkbox");

            writer.RenderBeginTag(HtmlTextWriterTag.Input);

            writer.RenderEndTag();

        }

 

        public string NodeStyle

        {

            set { this._nodeStyle = value; }

        }

     }

}

 

To use the class above, you also need to create your own custom TreeView that will use the custom TreeNode class. It can be done by creating a class that will inherits the TreeView class and override the CreateTreeNode method. The CreateTreeNode method will return the class that should represent a TreeNode:

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Text;

using System.Web.UI;

using System.Web.UI.WebControls;

 

namespace Test

{

    [DefaultProperty("Text")]

    [ToolboxData("<{0}:MyTreeView runat=server></{0}:MyTreeView>")]

    public class MyTreeView : TreeView

    {

        protected override TreeNode CreateNode()

        {

            return new MyTreeNode();

        }   

    }

}

 

Now you only need to add your custom TreeView to the Page and add your TreeNode to the Nodes collection of the TreeView:

 

<%@ Page Language="C#"  %>

<%@ Register TagPrefix="test" Namespace="Test" %>

 

<html>

<head id="Head1" runat="server">

    <title>Untitled Page</title>

</head>

 

<body>

    <form id="form1" runat="server">

    <div>

        <test:MyTreeView ID="MyTreeView1" runat="server">

            <Nodes>

                <test:MyTreeNode NodeStyle="color:#ff0000" Value="New Node" Text="New Node">               

                    <test:MyTreeNode NodeStyle="background:#00ff00" Value="New Node" Text="New Node" />

                </test:MyTreeNode>

            </Nodes>

        </test:MyTreeView>

    </div>

    </form>

</body>

</html>

 

You can also add your node dynamically to your TreeView:

 

MyTreeNode node = new MyTreeNode();

node.Text = "My added TreeNode";

 

MyTreeView1.Nodes.Add(node);

Posted: Wednesday, March 09, 2005 - 22:48 GMT+1    Print     E-mail    Comments (14)
Feedback
re: Extend the TreeView's nodes. - Bertrand Le Roy

While the example is illustrative of how you can extend the tree, it should probably be pointed out that hover styles are available out of the box on treeview, and that you fortunately don't need to extend treeview for that.
Of course this is just an example. More complex applications could be to add context menus to the nodes, etc.
Posted: Thursday, March 10, 2005 - 00:43 GMT+1  
re: Extend the TreeView's nodes. - Fredrik Normén

Bertrand Le Roy:

Thanks for your feedback. I can agree with you. I have now updated the example so it will now add a Style attribute to the <a> element of each node.
Posted: Thursday, March 10, 2005 - 08:16 GMT+1  
re: Extend the TreeView's nodes. - Ran Davidovitz

I think that microsoft did a very bad work with the treenode.

Lets say i want to do a very simple job - Add a threestate checkbox before each node.
The job is almost imposible, How can i save the state of each new control in the node.
for starters I must use reflectino to invoke internal and private methods or properties.
But how can I get a unieqe name of the node? (to save and reload the data)

If you have anyow to do it idea how to do it please write smt....

Thanks (love your blog)
Posted: Saturday, June 18, 2005 - 08:10 GMT+1  
re: Extend the TreeView's nodes. - Fredrik Normén

Ran:

You can set the ShowCheckBoxes to true to automatically add checkboxes before any node. The CheckedNodes property will have all the nodes that are selected. Is this something you was looking for?
Posted: Wednesday, June 22, 2005 - 08:01 GMT+1  
re: Extend the TreeView's nodes. - Peter Brzezianski

1. Tip for Ran: you may probably override TreeNode.SaveViewState and LoadViewState to write additional info to state object. Haven't try that but method's name looks promising.

2. I have major problem with client callbacks after extending TreeNode class. To be precise: after following example shown above populating nodes on demand causes TreeView.RenderCallbackResult() return null reference exception which is nicely rendered where my new nodes suppouse to be... Research and debuging indicates that there is some problem with posting my derived node type to server.
Thanks in advance for any info...
Posted: Friday, October 07, 2005 - 11:14 GMT+1  
re: Extend the TreeView's nodes. - wyx2000

I just copied your code, when I create node with
new MyTreeNode("text","value"), it says "error CS1501: No overload for method 'MyTreeNode' takes '2' arguments]
"
and then I found it prompts in VS that TreeNode is not inheritable, any idea?
Posted: Saturday, October 15, 2005 - 08:31 GMT+1  
re: Extend the TreeView's nodes. - Ketan Shah

Ran,

I agree with you that MS has not done well w.r.t making the treenode extensible.

Peter,
I overrode the SaveViewState and the LoadViewState methods in my dervied TreeNode implementation. On postbacks (in debug mode) I can break into the SaveViewState but cannot into the LoadViewState. Inshort, the LoadViewState is never called. I have been breaking my head on this one for a long time. Also, the TreeNode implements the IStateManager, but the ViewState property (Statebag) is not exposed to the dervied classes. I would have to create my own state bag. That is ridiculous!
Posted: Friday, November 04, 2005 - 21:06 GMT+1  
re: Extend the TreeView's nodes. - Andy Lam

Thanks. What a fantastic blog. This entry solved my problem of specifying styles in treenodes.

wyx2000,
TreeNode is not a sealed class.
How about declaring your own constructors that calls the base's constructors.
public myTreeNode(string text, string value) : base(text, value) { }

Ketan,
You don't need the base class' viewstate (or even need to create your own) to implement custom state management in a subclass of TreeNode.

Use the state management techniques described in the book - ASP.NET server controls and components. In particular, look in StyledCompositeLogin.cs for SaveViewState() and LoadViewState().
- code is available on the web. I know the code is for 1.1 but the state management code also works for 2.0 web controls.

For TreeNode subclasses, you cannot override TrackViewState() as described in the book, Just need to call it within each property you want to expose.

Good luck.
Posted: Wednesday, November 23, 2005 - 18:04 GMT+1  
re: Extend the TreeView's nodes. - cc

Thanks for the blog.

When I try to use it with "populate nodes from client", I get an error message in place of the treenode text which says "Object reference not set to an instance of an object."

If I remove the CreateNode override then the populate node from the client works fine but this time the additional control is not rendered on the postbacks.

Any ideas how to make this work with the client side node population.

thanks
Posted: Wednesday, January 04, 2006 - 21:01 GMT+1  
re: Extend the TreeView's nodes. - Stefaan Rillaert

cc,
When you'll use reflector on the CreateNode method of the standard TreeView you'll see that it calls special TreeNode constructor :

protected internal virtual TreeNode CreateNode()
{
return new TreeNode(this, false);
}

This constructor is defined in TreeNode as :

protected internal TreeNode(TreeView owner, bool isRoot) : this()
{
this._owner = owner;
this._isRoot = isRoot;
}

A PopulateNodesFromClient will call the GetCallbackResult() method on the TreeView during the callback. GetCallbackResult() will call CreateNode() during its execution (reflector again) and then expects a node which has a reference to his owner (the TreeView itself) to retrieve style properties on the TreeView.
So the only solution is to create such a node yourself in the CreateNode() method, this can be done by adding the constructors

public class MyTreeNode : TreeNode
{
public MyTreeNode() {
}

protected internal MyTreeNode(TreeView owner, bool isRoot) : base(owner, isRoot) {
}
}

to your custom TreeNode and writing CreateTreeNode as :

public class MyTreeView : TreeView
{
protected override TreeNode CreateNode() {
return new MyTreeNode(this, false);
}
}

This seems to solve the problem. Hope this helps.
Posted: Thursday, January 05, 2006 - 16:18 GMT+1  
how can i get the text of select tag that i added to my treenode - reza zareian

I added a select tag to each node of my tree I can get the value of each node select tag but I want to get selected option text can anyone help me?
Posted: Friday, June 08, 2007 - 18:08 GMT+1  
ForeColor property for this treenode class - Ahsan Murshed

Can you help me how to add a forecolor property in this class?
I need your help.
I try with it, but failure,

private Color forecolor;
public Color ForeColor{set this.forecolor=value;}

Regards
Ahsan
Posted: Thursday, August 21, 2008 - 11:38 GMT+1  
When you postback treenodes lose the format. - Ray

The page when loads, formats the treeview and nodes as in styles. but if i do a postback or call ajax popup extender then the nodes loose the format/styles. What I noticed is it gets the format of link (a href). Any idea why it would do like that.
Posted: Tuesday, September 29, 2009 - 19:45 GMT+1  
How i can store state of the radio button - Anand

please any one write the code to store the radion button state.
i have created custom control by using this render method.by using this control, i'm populating dyanmic data with input radio button.

But if i click button control, page getting postback.after refreshing page the radio button checked values are lost.

please i need it very urgent.
Posted: Tuesday, January 12, 2010 - 16:34 GMT+1  

Add feedback
Subject:
Name:
URL:
Message:




Please enter the text from the image:   

 
   fredrik.nsquared2.com - 2007