Inheriting from the TreeNode class

A

Alexander Walker

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
 
S

Steven Cheng[MSFT]

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()
: base()
{
}

public CustomTreeNode(
TreeView owner, bool isRoot)
: base(owner, 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.)






--------------------
| From: "Alexander Walker" <[email protected]>
| Subject: Inheriting from the TreeNode class
| Date: Sun, 15 Jan 2006 05:07:28 -0000
| Lines: 63
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
| X-RFC2646: Format=Flowed; Original
| Message-ID: <#[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| NNTP-Posting-Host: 84-12-165-60.dyn.gotadsl.co.uk 84.12.165.60
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftngp13.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:32475
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
|
| 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
|
|
|
 
A

Alexander Walker

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()
: base()
{
}

public CustomTreeNode(
TreeView owner, bool isRoot)
: base(owner, 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
 
S

Steven Cheng[MSFT]

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.)

--------------------
| From: "Alexander Walker" <[email protected]>
| References: <#[email protected]>
<[email protected]>
| Subject: Re: Inheriting from the TreeNode class
| Date: Wed, 18 Jan 2006 22:27:31 -0000
| Lines: 140
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
| Message-ID: <uM#[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| NNTP-Posting-Host: 84.12.20.49
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:32578
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
|
| 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()
| : base()
| {
| }
|
| public CustomTreeNode(
| TreeView owner, bool isRoot)
| : base(owner, 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
|
|
|
|
 
A

Alexander Walker

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

| 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.)
|
| --------------------
|| From: "Alexander Walker" <[email protected]>
|| References: <#[email protected]>
| <[email protected]>
|| Subject: Re: Inheriting from the TreeNode class
|| Date: Wed, 18 Jan 2006 22:27:31 -0000
|| Lines: 140
|| X-Priority: 3
|| X-MSMail-Priority: Normal
|| X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
|| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
|| Message-ID: <uM#[email protected]>
|| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
|| NNTP-Posting-Host: 84.12.20.49
|| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
|| Xref: TK2MSFTNGXA02.phx.gbl
| microsoft.public.dotnet.framework.aspnet.webcontrols:32578
|| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
||
|| 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()
|| : base()
|| {
|| }
||
|| public CustomTreeNode(
|| TreeView owner, bool isRoot)
|| : base(owner, 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
||
||
||
||
|
 
A

Alexander Walker

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

| 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
|
 
S

Steven Cheng[MSFT]

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.)


--------------------
| From: "Alexander Walker" <[email protected]>
| References: <#[email protected]>
<[email protected]>
<uM#[email protected]>
<Ign3#[email protected]>
<[email protected]>
| Subject: Re: Inheriting from the TreeNode class
| Date: Fri, 20 Jan 2006 20:13:33 -0000
| Lines: 127
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
| Message-ID: <[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| NNTP-Posting-Host: 81-6-217-221.gotadsl.co.uk 81.6.217.221
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP15.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:32692
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
|
| 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
|
| | | 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
| |
|
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top