为TreeNode添加自定义属性

来源:互联网 发布:一洋seo管家下载 编辑:程序博客网 时间:2024/05/22 01:56

 

为TreeNode添加自定义属性,需要重写TreeNode,例如,添加一个NodeType属性,类型为Int类型:

public class myTreeNode : TreeNode
    {
        private int nodeType;

        public int NodeType
        {
            get
            { return nodeType; }
            set
            { nodeType = value; }
        }

        public myTreeNode(): base()
        {
            //
            // TODO: Add constructor logic here
            //
        }

 public myTreeNode(string text, string value, int nodeType): base(text, value)
        {     
            this.NodeType = nodeType;
        }
    }
在页面中添加一个TreeView 控件,和button控件,代码如下:
protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            TreeView1.Nodes.Add(new myTreeNode("node 1", "A",99));
            Button1.Text = (TreeView1.Nodes[0] as myTreeNode).nodeType.ToString();
        }
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        Button1.Text = (TreeView1.Nodes[0] as myTreeNode ).nodeType.ToString() ;
    }
但是在 Button的click事件中,却出现如下异常:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 14:     protected void Button1_Click(object sender, EventArgs e)
Line 15:     {
Line 16:         Button1.Text = (TreeView1.Nodes[0] as myTreeNode).nodeType.ToString();
Line 17:     }
Line 18: }

Source File: c:/Inetpub/wwwroot/test/Default.aspx.cs    Line: 16

但是在pageload中为Button的Text赋值没有问题,在点击Button之后,页面postback之后,出现这个异常,这好像说明是告诉我们,页面PostBack之后,就不能将TreeNode转化成自定义的TreeNode类型。
因此,我们需要重写TreeView 控件,将TreeView的TreeNode类型强制转化为自定义的TreeNode 类型:

public class myTreeView : TreeView
    {       

        public myTreeView()
        {
            //
            // TODO: Add constructor logic here
            //
        }
       
        protected override TreeNode CreateNode()
        {
            return new myTreeNode();
        }
    }

然后,运行程序,发现原来的异常消失了,但是另一个问题出现了,就是我们在pageload里面给TreeNode的赋值,在页面Postback之后,我们发现nodeType的制变为0,属性Text和value也变为null,也就是说我们的值没有保存,在页面Postack之后就丢失了,在反编译工具查看一下Treeview和Treenode的源代码,发现,Text和value,还有其他的一些属性是保存在viewstate中的,所以我们需要在自定义的TreeNode类中重写两个方法:SaveViewStateLoadViewState
下面是我的自定义的TreeNode的全部代码:

public class myTreeNode : TreeNode
    {
        private string NodeText = string.Empty;
        private string NodeURL = string.Empty;
        private int nodeType;

        public int NodeType
        {
            get
            { return nodeType; }
            set
            { nodeType = value; }
        }

      

        public myTreeNode(): base()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public myTreeNode(string text, string value, int nodeType): base(text, value)
        {     
            this.NodeType = nodeType;
        }


        protected override object SaveViewState()
        {
            object[] arrState = new object[4];
            arrState[0] = base.SaveViewState();
            arrState[1] = this.NodeText;
            arrState[2] = this.NodeURL;
            arrState[3] = this.nodeType;

            return arrState;
        }

        protected override void LoadViewState(object savedState)
        {
            if (savedState != null)
            {
                object[] arrState = savedState as object[];

                this.NodeText = (string)arrState[1];
                this.NodeURL = (string)arrState[2];
                this.nodeType = (int)arrState[3];
                base.LoadViewState(arrState[0]);
            }
        }

    }

这样,在页面Postback的时候,值就不会丢失了。
别忘了把控件的enableviewstate=false

 

 

一种可供参考的扩展实现思路(时间关系未验证)

步骤1. 继承 TreeNode 实现自己的 MyTreeNode,并重写 TreeNode.RenderPostText 方法
具体见: http://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.treenode.renderposttext.aspx

http://topic.csdn.net/u/20080805/11/21a4014a-490c-4eff-86e4-4908120f257e.html?seed=1171494412

步骤2. 继承 TreeView 实现自己的 MyTreeView,并重写 TreeView.CreateNode 方法,返回步骤1实现的 MyTreeNode(主要用于ViewState恢复)
具体见: http://msdn.microsoft.com/zh-cn/library/system.web.ui.webcontrols.treeview.createnode.aspx