C# – How to inherit from the treenode class

asp.netctreenodetreeview

I have a class that inherits from TreeNode, called ExtendedTreeNode. To add an object of this type to the treeview is not a problem. But how do I retrieve the object from the treeview?

I have tried this:

TreeNode node = tvManual.Find("path/to/node"); // tvManual is a treeview

return ((ExtendedTreeNode)node).Property;

But this doesn't work. I get this error: Unable to cast object of type 'System.Web.UI.WebControls.TreeNode' to type 'PCK_Web_new.Classes.ExtendedTreeNode'.

What do I have to do to make this work?

———— SOLUTION —————–

[Edit] My custom TreeNode class looks like this:

public class ExtendedTreeNode : TreeNode
{
    private int _UniqueId;

    public int UniqueId
    {
        set { _UniqueId = value; }
        get { return _UniqueId; }
    }
    public ExtendedTreeNode()
    {
    }
}

And this way I add Nodes to my treeview:

ExtendedTreeNode TN2 = new ExtendedTreeNode();

TN2.Text = "<span class='Node'>" + doc.Title + "</span>";
TN2.Value = doc.ID.ToString();
TN2.NavigateUrl = "ViewDocument.aspx?id=" + doc.ID + "&doc=general&p=" + parent;
TN2.ImageUrl = "Graphics/algDoc.png";
TN2.ToolTip = doc.Title;
TN2.UniqueId = counter;

tvManual.FindNode(parent).ChildNodes.Add(TN2);

And this way I retrieve my ExtendedTreeNode object:

TreeNode node = tvManual.Find("path/to/node");
ExtendedTreeNode extNode = node as ExtendedTreeNode;
return extNode.UniqueId;

I am using .NET 3.5 SP1

Best Answer

I found a Microsoft example for how to implement an ASP.NET TreeView with tags here.

Some important steps that are necessary besides just subclassing TreeNode and adding a Tag property are:

You must subclass TreeView and override the CreateNode method:

public sealed class TaggedTreeView : TreeView {
   protected override TreeNode CreateNode() {
      return new TaggedTreeNode(this, false);
   }
}

This prevents the TreeView from overwriting your new nodes with TreeNodes instead of with your extended type of node.

You will need to have that particular constructor available. (It seems to work using the default constructor, too, but there's a good chance there's a good reason why they used this one.)

public sealed class TaggedTreeNode : TreeNode {
   object _Tag;

   public object Tag { get { return _Tag; } set { _Tag = value; } }

   ...

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

In order to use the extended TreeView you will need a Register line like the following in your markup to import the type:

<%@ Register TagPrefix="asp" Namespace="MyNamespace" Assembly="MyAssembly" %>

...

<asp:TaggedTreeView ID="taggedTreeView" runat="server" />

You must also override LoadViewState and SaveViewState in your inherited TreeNode class:

public sealed class TaggedTreeNode : TreeNode {

   ...

   protected override void LoadViewState(object state) {
      var arrState = (object[])state;
      _Tag = arrState[0];
      base.LoadViewState(arrState[1]);
   }

   protected override object SaveViewState() {
      var arrState = new object[2];
      arrState[1] = base.SaveViewState();
      arrState[0] = _Tag;
      return arrState;
   }

This allows the TreeView to preserve the value of your Tag properties between postbacks.