search
Twitter Rss Feeds
MicrosoftArticlesForumsGroups
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml/Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

Web ProgrammingArticlesForumsGroups
JavaScript
ASP
ASP.NET
Web Services

Non-MicrosoftArticlesForumsGroups
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

DatabasesArticlesForumsGroups
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsGroups
Microsoft Excel
Microsoft Word
Microsoft Powerpoint
Publisher
Money

Operating SystemsArticlesForumsGroups
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsGroups
Share Point
BizTalk
Site Server
Exhange Server
IIS
Transaction Server

Graphic DesignArticlesForumsGroups
Macromedia Flash
Adobe PhotoShop
Microsoft Expression

OtherArticlesForumsGroups
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Reviews
Search Engines
Resumes

 

Previous Thread:   Inheriting from the TreeNode class

1/15/2006 5:07:28 AM    Inheriting from the TreeNode class
Hello  
  
I have a written a class that inherits from the TreeNode class  
  
I want to use the inherited TreeNode class to attach custom properties to  
  
the nodes in a TreeView web control  
  
I am trying to use the TreeNodePopulate event to read the custom property  
  
when the user expands a node  
  
The problem is that the custom node is not recognised when the event fires  
  
after the page has been rendered  
  
How can I access the custom node during postbacks, I get the feeling that  
  
the custom node isn't being created, even though I've overridden the  
  
CreateNode method, is there something else I should do? Do I need to  
  
override other methods that persist the custom properties of the custom  
  
treenode? Am I doing this the wrong way? Should I take an entirely different  
  
approach?  
  
Here is some of the code  
  
public class CustomTreeView : TreeView  
  
{  
  
protected override TreeNode CreateNode()  
  
{  
  
return new CustomTreeNode();  
  
}  
  
}  
  
public class CustomTreeNode : TreeNode  
  
{  
  
private int customInt;  
  
public int CustomInt  
  
{  
  
get  
  
{  
  
return customInt;  
  
}  
  
set  
  
{  
  
customInt= value;  
  
}  
  
}  
  
}  
  
protected void customTreeView_TreeNodePopulate(object sender,  
  
TreeNodeEventArgs e)  
  
{  
  
CustomTreeNode node = e.Node as CustomTreeNode;  
  
// node == null  
  
// i need to access node.CustomInt  
  
...  
  
}  
  
Thanks  
  
Alex

1/16/2006 4:39:22 AM    RE: Inheriting from the TreeNode class
Hi Alex,  
  
Welcome to ASPNET newsgroup.  
  
As for the creating custom TreeView with custom TreeNode class question,  
  
based on my understanding we need to take care of the following things when  
  
we need to extend the TreeNode or its properties:  
  
1. For the Custom TreeNode's constructor, we'd better override the  
  
TreeNode(TreeView owner, bool isRoot)  one and call the base class's  
  
constructor  in our constructor . e.g:  
  
protected override TreeNode CreateNode()  
  
{  
  
return new CustomTreeNode(this,false);  
  
}  
  
2. Also, for the properties in TreeNode, that won't be automatically saved  
  
if we do not persist them when the page load/save states for the Control...  
  
So for our CustomInt property, we have to override the TreeNode's  
  
SaveViewState and LoadViewState (of IStateManager interface) to explictly  
  
store the CustomInt value (in additional to base class's States infol...).  
  
to make this clear, below is a simple modified version of the Custom  
  
TreeView class and TreeNode class, you can have a look according to the  
  
above things:  
  
=======================  
  
public class CustomTreeView : TreeView  
  
{  
  
protected override TreeNode CreateNode()  
  
{  
  
return new CustomTreeNode(this,false);  
  
}  
  
}  
  
public class CustomTreeNode : TreeNode  
  
{  
  
private int customInt;  
  
public int CustomInt  
  
{  
  
get  
  
{  
  
return customInt;  
  
}  
  
set  
  
{  
  
customInt = value;  
  
}  
  
}  
  
public CustomTreeNode()  
  
{  
  
}  
  
public CustomTreeNode(  
  
TreeView owner, bool isRoot)  
  
{  
  
}  
  
protected override void LoadViewState(object state)  
  
{  
  
object[] arrState = state as object[];  
  
this.customInt = (int)arrState[1];  
  
base.LoadViewState(arrState[0]);  
  
}  
  
protected override object SaveViewState()  
  
{  
  
object[] arrState = new object[2];  
  
arrState[0] = base.SaveViewState();  
  
arrState[1] = this.customInt;  
  
return arrState;  
  
}  
  
}  
  
=============================  
  
Hope helps. Thanks,  
  
Steven Cheng  
  
Microsoft Online Support  
  
Get Secure! www.microsoft.com/security  
  
(This posting is provided "AS IS", with no warranties, and confers no  
  
rights.)  
  
--------------------  
  
microsoft.public.dotnet.framework.aspnet.webcontrols:32475  
  
fires  
  
different

1/18/2006 10:27:31 PM    Re: Inheriting from the TreeNode class
Hi Steven  
  
When I tried to use the OnTreeNodePopulate event to access my custom node in the  
  
callback, the custom property did not have its value, I was forced to use the  
  
FindNode method of the TreeView instance to get a reference to the  
  
CustomTreeNode and it did have its value, only problem with using FindNode is  
  
that the found node doesn't seem to allow child nodes to be added to it. Is  
  
there something missing from my inherited TreeNode or TreeView class that once  
  
added will allow me to get a reference to a CustomTreeNode instance that has its  
  
CustomInt value using the following line of code in the OnTreeNodePopulate event  
  
CustomTreeNode node = e.Node as ShopTreeNode;  
  
Here is a brief example:  
  
protected void CustomOnTreeNodePopulate(Object source, TreeNodeEventArgs e)  
  
{  
  
// get the CustomTreeNode instance  
  
//  
  
CustomTreeNode node1 = e.Node as ShopTreeNode;  
  
// node1.CustomInt == 0 even though a value was  
  
// given to it before the page rendered  
  
//  
  
int emptyCustomInt = node1.CustomInt;  
  
// the following line is required to find the node  
  
// and get a reference to it, but adding new nodes to  
  
// the ChildNodes of this reference does not work,  
  
// instead the old reference (node1) must be used  
  
// for adding child nodes  
  
//  
  
CustomTreeNode node2 = customTreeView.FindNode(node1.ValuePath) as  
  
CustomTreeNode;  
  
// I can now access the CustomInt :)  
  
//  
  
int customInt = node2.CustomInt;  
  
// I want to add a new node to the CustomTreeNode instance  
  
//  
  
CustomTreeNode node = new CustomTreeNode();  
  
newNode.CustomInt = 5;  
  
// the following line appears to have no effect :(  
  
//  
  
node2.ChildNodes.Add(newNode);  
  
}  
  
For the time being I can use the technique above but I think that my  
  
CustomTreeView and CustomTreeNode are not very friendly because they dont behave  
  
as they are expected to behave, somebody other than myself who is consuming the  
  
CustomTreeView and CustomTreeNode classes would have a hard time figuring out  
  
what was going on, they would either be figuring out why nodes added to the  
  
CustomTreeNode instance dont appear or figuring out why the custom property has  
  
lost its value, depending on how they obtain a reference to the CustomTreeNode  
  
instance. Am I using the wrong technique to get a reference to the  
  
CustomTreeNode instance in the OnTreeNodePopulate event? Any ideas on whats  
  
missing from the CustomTreeView and CustomTreeNode class? Do I need to create a  
  
new OnTreeNodePopulate event that has a CustomTreeNodeEventArgs argument?  
  
Here is the source for the CustomTreeView  
  
using System;  
  
using System.Collections.Generic;  
  
using System.ComponentModel;  
  
using System.Text;  
  
using System.Web.UI;  
  
using System.Web.UI.WebControls;  
  
public class CustomTreeView : TreeView  
  
{  
  
protected override TreeNode CreateNode()  
  
{  
  
return new CustomTreeNode(this, false);  
  
}  
  
}  
  
Here is the source for the CustomTreeNode  
  
using System;  
  
using System.Collections.Generic;  
  
using System.ComponentModel;  
  
using System.Text;  
  
using System.Web.UI;  
  
using System.Web.UI.WebControls;  
  
public class CustomTreeNode: TreeNode  
  
{  
  
private int customInt;  
  
public CustomTreeNode()  
  
{  
  
}  
  
public CustomTreeNode(  
  
TreeView owner, bool isRoot)  
  
{  
  
}  
  
protected override void LoadViewState(object state)  
  
{  
  
object[] arrState = state as object[];  
  
this.customInt = (int)arrState[1];  
  
base.LoadViewState(arrState[0]);  
  
}  
  
protected override object SaveViewState()  
  
{  
  
object[] arrState = new object[2];  
  
arrState[0] = base.SaveViewState();  
  
arrState[1] = this.customInt;;  
  
return arrState;  
  
}  
  
public int CustomInt  
  
{  
  
get  
  
{  
  
return customInt;  
  
}  
  
set  
  
{  
  
customInt = value;  
  
}  
  
}  
  
}  
  
Thank you  
  
Alex

1/19/2006 2:43:56 AM    Re: Inheriting from the TreeNode class
Hi Alexander,  
  
How are you defining the CustomTreeNodes in the CustomTreeView control?  
  
I've just performed some test by statically declaring them in aspx template  
  
or programmatically add through code, seems the CustomInt property can be  
  
persited and read out well. Also, in the OnPopulate event, I can add child  
  
nodes correctly....  Here is my test page and the code behind file:  
  
(custom treeview and treenode class source remains the same as the one I  
  
posted you last time):  
  
=================aspx===========  
  
<%@ Register Assembly="WebControlLib" Namespace="WebControlLib"  
  
TagPrefix="cc1" %>  
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  
<html xmlns="http://www.w3.org/1999/xhtml" >  
  
<head runat="server">  
  
<title>Untitled Page</title>  
  
</head>  
  
<body>  
  
<form id="form1" runat="server">  
  
<div>  
  
<cc1:CustomTreeView ID="CustomTreeView1" runat="server"  
  
ExpandDepth="0"  
  
OnSelectedNodeChanged="CustomTreeView1_SelectedNodeChanged"  
  
OnTreeNodeExpanded="CustomTreeView1_TreeNodeExpanded"  
  
OnTreeNodePopulate="CustomTreeView1_TreeNodePopulate"  
  
<Nodes >  
  
<cc1:CustomTreeNode Text="Node1" Value="Node1"  
  
SelectAction="SelectExpand"  >  
  
<cc1:CustomTreeNode Text="Node11" Value="Node11"  
  
SelectAction="SelectExpand"  ></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node12"  
  
Value="Node12"></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node13"  
  
Value="Node13"></cc1:CustomTreeNode>  
  
</cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node2" Value="Node2">  
  
<cc1:CustomTreeNode Text="Node21" Value="Node21"  
  
PopulateOnDemand="True" CustomInt="0" ></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node22" Value="Node22"  
  
PopulateOnDemand="True" CustomInt="1"></cc1:CustomTreeNode>  
  
</cc1:CustomTreeNode>  
  
</Nodes>  
  
</cc1:CustomTreeView>  
  
</div>  
  
</form>  
  
</body>  
  
========code behind===========  
  
using System;  
  
using System.Data;  
  
using System.Configuration;  
  
using System.Collections;  
  
using System.Web;  
  
using System.Web.Security;  
  
using System.Web.UI;  
  
using System.Web.UI.WebControls;  
  
using System.Web.UI.WebControls.WebParts;  
  
using System.Web.UI.HtmlControls;  
  
public partial class CustTreeView : System.Web.UI.Page  
  
{  
  
protected void Page_Load(object sender, EventArgs e)  
  
{  
  
}  
  
protected void CustomTreeView1_SelectedNodeChanged(object sender,  
  
EventArgs e)  
  
{  
  
Response.Write("<br/>CustomTreeView1_SelectedNodeChanged ");  
  
}  
  
protected void CustomTreeView1_TreeNodeExpanded(object sender,  
  
TreeNodeEventArgs e)  
  
{  
  
Response.Write("<br/>CustomTreeView1_TreeNodeExpanded ");  
  
Response.Write("<br/>Node: " + e.Node.GetType());  
  
}  
  
protected void CustomTreeView1_TreeNodePopulate(object sender,  
  
TreeNodeEventArgs e)  
  
{  
  
Response.Write("<br/>CustomTreeView1_TreeNodePopulate ");  
  
WebControlLib.CustomTreeNode cn = e.Node as  
  
WebControlLib.CustomTreeNode;  
  
Response.Write("<br/>Node.CustomInt: " + cn.CustomInt );  
  
for (int i = 0; i < 5; i++)  
  
{  
  
WebControlLib.CustomTreeNode ncn = new  
  
WebControlLib.CustomTreeNode();  
  
ncn.Text = "New Child Node " + i;  
  
ncn.Value = cn.Text;  
  
cn.ChildNodes.Add(ncn);  
  
}  
  
}  
  
}  
  
================================  
  
Thanks,  
  
Steven Cheng  
  
Microsoft Online Support  
  
Get Secure! www.microsoft.com/security  
  
(This posting is provided "AS IS", with no warranties, and confers no  
  
rights.)  
  
--------------------  
  
<CSxlZblGGHA.3944@TK2MSFTNGXA02.phx.gbl>  
  
microsoft.public.dotnet.framework.aspnet.webcontrols:32578  
  
in the  
  
the  
  
FindNode is  
  
Is  
  
once  
  
has its  
  
OnTreeNodePopulate event  
  
e)  
  
behave  
  
consuming the  
  
out  
  
the  
  
property has  
  
CustomTreeNode  
  
whats  
  
create a

1/20/2006 8:05:31 PM    Re: Inheriting from the TreeNode class
Hello Steve  
  
Thank you for your response  
  
I built your example and it worked. I altered it slightly so that it was more  
  
like the implementation I have in my application and it stopped working.  
  
Specifically the nodes did not expand any more. I removed the OnTreeNodeExpanded  
  
event and set the EnableClientScript property to true on the aspx page, if you  
  
try this,  I think that you will get the same behaviour that I described in my  
  
previous message  
  
Thanks  
  
Alex  
  
"Steven Cheng[MSFT]" <stcheng@online.microsoft.com> wrote in message  
  
news:Ign3%23IKHGHA.3152@TK2MSFTNGXA02.phx.gbl...

1/20/2006 8:13:33 PM    Re: Inheriting from the TreeNode class
I forgot to mention that I also set the PopulateOnDemand property of the nodes  
  
to true and the ExpandDepth to 2  
  
To avoid any confusion I will include the source here  
  
=================aspx===========  
  
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CustTreeView.aspx.cs"  
  
Inherits="CustTreeView" %>  
  
<%@ Register Assembly="WebControlLib" Namespace="WebControlLib" TagPrefix="cc1"  
  
%>  
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  
<html xmlns="http://www.w3.org/1999/xhtml">  
  
<head id="Head1" runat="server">  
  
<title>Untitled Page</title>  
  
</head>  
  
<body>  
  
<form id="form1" runat="server">  
  
<div>  
  
<cc1:CustomTreeView ID="CustomTreeView1" runat="server"  
  
ExpandDepth="2" OnSelectedNodeChanged="CustomTreeView1_SelectedNodeChanged"  
  
EnableClientScript="true" OnTreeNodePopulate="CustomTreeView1_TreeNodePopulate">  
  
<nodes>  
  
<cc1:CustomTreeNode Text="Node1" Value="Node1"  
  
SelectAction="SelectExpand"  >  
  
<cc1:CustomTreeNode Text="Node11" Value="Node11"  
  
SelectAction="SelectExpand"  ></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node12"  
  
Value="Node12"></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node13"  
  
Value="Node13"></cc1:CustomTreeNode>  
  
</cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node2" Value="Node2">  
  
<cc1:CustomTreeNode Text="Node21" Value="Node21"  
  
PopulateOnDemand="True" CustomInt="0" ></cc1:CustomTreeNode>  
  
<cc1:CustomTreeNode Text="Node22" Value="Node22"  
  
PopulateOnDemand="True" CustomInt="1"></cc1:CustomTreeNode>  
  
</cc1:CustomTreeNode>  
  
</nodes>  
  
</cc1:CustomTreeView>  
  
</div>  
  
</form>  
  
</body>  
  
</html>  
  
========code behind===========  
  
using System;  
  
using System.Data;  
  
using System.Configuration;  
  
using System.Collections;  
  
using System.Web;  
  
using System.Web.Security;  
  
using System.Web.UI;  
  
using System.Web.UI.WebControls;  
  
using System.Web.UI.WebControls.WebParts;  
  
using System.Web.UI.HtmlControls;  
  
public partial class CustTreeView : System.Web.UI.Page  
  
{  
  
protected void Page_Load(object sender, EventArgs e)  
  
{  
  
}  
  
protected void CustomTreeView1_SelectedNodeChanged(object sender, EventArgs  
  
e)  
  
{  
  
Response.Write("<br/>CustomTreeView1_SelectedNodeChanged ");  
  
WebControlLib.CustomTreeNode cn = CustomTreeView1.SelectedNode as  
  
WebControlLib.CustomTreeNode;  
  
Response.Write("<br/>Node.CustomInt: " + cn.CustomInt);  
  
Response.Write("<br/>Node.CustomInt: " + cn.CustomInt);  
  
}  
  
protected void CustomTreeView1_TreeNodePopulate(object  
  
sender,TreeNodeEventArgs e)  
  
{  
  
Response.Write("<br/>CustomTreeView1_TreeNodePopulate ");  
  
WebControlLib.CustomTreeNode cn = e.Node as  
  
WebControlLib.CustomTreeNode;  
  
Response.Write("<br/>Node.CustomInt: " + cn.CustomInt);  
  
//Response.Write("<br/>Node.CustomInt2: " + cn.CustomInt2);  
  
//Response.Write("<br/>Node.CustomInt3: " + cn.CustomInt3);  
  
//Response.Write("<br/>Node.CustomInt4: " + cn.CustomInt4);  
  
for (int i = 0; i < 5; i++)  
  
{  
  
WebControlLib.CustomTreeNode ncn = new  
  
WebControlLib.CustomTreeNode();  
  
ncn.Text = "New Child Node " + i;  
  
ncn.Value = i.ToString();  
  
ncn.PopulateOnDemand = true;  
  
ncn.CustomInt = i;  
  
cn.ChildNodes.Add(ncn);  
  
}  
  
}  
  
}  
  
Thanks again  
  
Alex  
  
"Alexander Walker" <alex@noemail.noemail> wrote in message  
  
news:O6OxfzfHGHA.3728@tk2msftngp13.phx.gbl...  
  
OnTreeNodeExpanded

1/23/2006 2:49:07 PM    Re: Inheriting from the TreeNode class
Hey Alex,  
  
Thanks for your response.  
  
I've reviewed the code and performed some further tests. I think the cause  
  
of the TreeNode not expand behavior is the "OnTreeNodeExpanded" event, we  
  
must have an eventhandler for this event, otherwise, the TreeNode won't be  
  
able to expand even if we configure PopuplateOnDemand for treeNode and  
  
registered the TreeNodePopulated event handler...  
  
Also, this is the TreeView's default behavior , not specific to our custom  
  
TreeView implementation...  
  
Thanks,  
  
Steven Cheng  
  
Microsoft Online Support  
  
Get Secure! www.microsoft.com/security  
  
(This posting is provided "AS IS", with no warranties, and confers no  
  
rights.)  
  
--------------------  
  
<CSxlZblGGHA.3944@TK2MSFTNGXA02.phx.gbl>  
  
<uM#Je5HHGHA.140@TK2MSFTNGP12.phx.gbl>  
  
<Ign3#IKHGHA.3152@TK2MSFTNGXA02.phx.gbl>  
  
<O6OxfzfHGHA.3728@tk2msftngp13.phx.gbl>  
  
microsoft.public.dotnet.framework.aspnet.webcontrols:32692  
  
nodes  
  
CodeFile="CustTreeView.aspx.cs"  
  
TagPrefix="cc1"  
  
OnSelectedNodeChanged="CustomTreeView1_SelectedNodeChanged"  
  
OnTreeNodePopulate="CustomTreeView1_TreeNodePopulate">  
  
EventArgs  
  
was more  
  
if you  
  
described in my


Pete's Blog   |    Pete's Resume   |    Robbe's Blog   |    Robbe's Resume   |    Archive #2   |    Archive #3   |    Dotnetslackers   |    XmlPitStop   |    Advertise   |   Contact Us   |   Privacy   |   Copyright (c) 2000 - 2009 eggheadcafe.com  All rights reserved.