treenode.cs

来自「浏览器端看到树型目录结构,用户可以完整地看到像windows资源管理器一样的效果」· CS 代码 · 共 1,240 行 · 第 1/3 页

CS
1,240
字号
                CheckedExpandable = false;
            }
        }

        /// <summary>
        /// Returns a reference to the parent TreeView.
        /// </summary>
        protected internal TreeView ParentTreeView
        {
            get
            {
                if (_treeview == null)
                {
                    // Get the parent treeview
                    TreeNode prev = this;
                    while (prev.Parent is TreeNode)
                        prev = (TreeNode)prev.Parent;
                    _treeview = (TreeView)prev.Parent;
                }
                return _treeview;
            }
            set
            {
                _treeview = value;
                foreach (TreeNode node in Nodes)
                {
                    node.ParentTreeView = value;
                }
            }
        }

        /// <summary>
        /// Returns the level in the tree.
        /// </summary>
        protected int Level
        {
            get
            {
                if (_level == -1)
                {
                    Object prev = Parent;
                    while (prev is TreeNode)
                    {
                        prev = ((TreeNode)prev).Parent;
                        _level++;
                    }
                    return ++_level;
                }
                else
                    return _level;
            }
        }

        /// <summary>
        /// Returns the number of sibling TreeNodes before this one.
        /// </summary>
        internal int SibIndex
        {
            get
            {
                if (Parent != null)
                {
                    if (Parent is TreeNode)
                        return ((TreeNode)Parent).Nodes.IndexOf(this);
                    else
                        return ((TreeView)Parent).Nodes.IndexOf(this);
                }
                else
                    return -1;
            }

/*
                if (_sibIndex == -1)
                {
                    TreeNode node = this;
                    while (node != null)
                    {
                        _sibIndex++;
                        node = node.GetPreviousSibling();
                    }
                }
                return _sibIndex;
            }
            set
            {
                _sibIndex = value;
            }
*/
        }

        /// <summary>
        /// Gets the collection of nodes in the control.
        /// </summary>
        [
        Category("Data"),
        DefaultValue(null),
        MergableProperty(false),
        Browsable(false),
        PersistenceMode(PersistenceMode.InnerDefaultProperty),
        ResDescription("TreeNodes"),
        ]
        public virtual TreeNodeCollection Nodes
        {
            get { return _Nodes; }
        }

        /// <summary>
        /// Initializes a new instance of a TreeNode.
        /// </summary>
        public TreeNode() : base()
        {
            _level = -1;
            _treeview = null;
            _strInheritedType = null;
            _NodeTypeIndex = -1;
            _bBound = false;
            _Nodes = new TreeNodeCollection(this);
        }

        /// <summary>
        /// Event handler for the OnSelectedIndexChange event.
        /// </summary>
        /// <param name="e">Event arguments</param>
        /// <returns>true to bubble, false to cancel</returns>
        protected virtual bool OnSelectedIndexChange(EventArgs e)
        {
            return true;
        }

        /// <summary>
        /// Event handler for the OnExpand event.
        /// </summary>
        /// <param name="e">Event arguments</param>
        /// <returns>true to bubble, false to cancel</returns>
        protected virtual bool OnExpand(EventArgs e)
        {
            if (!Expanded && CanExpand())
            {
                Expanded = true;
                Object obj = FindNodeAttribute("Expandable");
                if (obj == null)
                {
                    obj = Expandable; // get default value if none is explicitly set
                }

                if ((ExpandableValue)obj == ExpandableValue.CheckOnce)
                    CheckedExpandable = true;

                if (!_bBound)
                    ReadXmlSrc();

                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// Event handler for the OnCollapse event.
        /// </summary>
        /// <param name="e">Event arguments</param>
        /// <returns>true to bubble, false to cancel</returns>
        protected virtual bool OnCollapse(EventArgs e)
        {
            if (Expanded)
            {
                Expanded = false;
                // If this node was selected, unselect it and make the parent the selected node
                // Note: The client handles this nicely uplevel; we only need to do this downlevel
                if (! ParentTreeView.IsUpLevel)
                {
                    String strNewIndex = GetNodeIndex();
                    String strOldIndex = ParentTreeView.SelectedNodeIndex;
                    if (strOldIndex.StartsWith(strNewIndex) && strOldIndex != strNewIndex)
                    {
                        TreeViewSelectEventArgs e2 = new TreeViewSelectEventArgs(strOldIndex, strNewIndex);
                        ParentTreeView.DoSelectedIndexChange(e2);
                        // Since this only gets called downlevel, we don't need to worry about other selection
                        // changes being queued-- this will be the only one, and so we can queue an event for it 
                        ParentTreeView._eventList.Add("s");
                        ParentTreeView._eventList.Add(e2);
                    }
                }
                return true;
            }
            else
                return false;
        }

        //
        // OnCheck
        //
	    /// <summary>
        /// Event handler for OnCheck event
        /// </summary>
        protected virtual bool OnCheck(EventArgs e)
        {
            Checked = !Checked;
            return true;
        }

        //
        // OnInit
        //
        /// <summary>
        /// Initializes the TreeNode.
        /// </summary>
        internal void OnInit()
        {
            if (Expanded)
            {
                Databind();
            }
        }

        /// <summary>
        /// Process the event string, calling the appropriate event handler.
        /// </summary>
        /// <param name="eventArg">Event argument.</param>
        /// <returns>true to bubble, false otherwise.</returns>
        private bool ProcessEvent(string eventArg)
        {
            int nSep = eventArg.IndexOf(',');
            if (nSep < 0)
                nSep = eventArg.Length;

            string strEvent = eventArg.Substring(0, nSep);
            EventArgs e = new EventArgs();
            if (strEvent.Equals("onexpand"))
                return OnExpand(e);
            else if (strEvent.Equals("oncollapse"))
                return OnCollapse(e);
            else if (strEvent.Equals("onselectedindexchange"))
                return OnSelectedIndexChange(e);
            else if (strEvent.Equals("oncheck"))
                return OnCheck(e);
            else
                return false;
        }

        /// <summary>
        /// Public entry point used by treeview to "bubble down" an event, thus freeing treenodes from having
        /// to include postback HTML for default treenode activity
        /// </summary>
        /// <param name="eventArg">Event argument.</param>
        internal virtual void LowerPostBackEvent(string eventArg)
        {
            ProcessEvent(eventArg);
        }

        /// <summary>
        /// Sets all items within the StateBag to be dirty
        /// </summary>
        protected internal override void SetViewStateDirty()
        {
            base.SetViewStateDirty();

            Nodes.SetViewStateDirty();
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>A new object that is a copy of this instance.</returns>
        public override object Clone()
        {
            TreeNode copy = (TreeNode)base.Clone();

            copy._strInheritedType = this._strInheritedType;
            copy._NodeTypeIndex = -1;
            copy._Nodes = (TreeNodeCollection)this._Nodes.Clone();
            
            // Fix parentage
            copy._Nodes.Parent = copy;
            if (copy._Nodes.Count > 0)
            {
                foreach (TreeNode tnode in copy._Nodes)
                {
                    tnode._Parent = copy;
                }
            }

            return copy;
        }

        /// <summary>
        /// Renders the node for uplevel browsers.
        /// </summary>
        /// <param name="output">The HtmlTextWriter object that receives the content.</param>
        protected override void RenderUpLevelPath(HtmlTextWriter output)
        {
            if (Type != String.Empty)
                output.AddAttribute("Type", Type);

            if (Expandable == ExpandableValue.CheckOnce)
                output.AddAttribute("Expandable", "checkOnce");
            else if (Expandable == ExpandableValue.Always)
                output.AddAttribute("Expandable", "always");
            if (CheckedExpandable)
                output.AddAttribute("checkedExpandable", "true");

            // Because of ExpandLevel, we need to distinguish between explicitly-declared false and default false.
            // Only the explicit false will be stored in ViewState.
            object b = ViewState["Expanded"];
            if (Expanded || (b != null && (bool)b == false))
                output.AddAttribute("Expanded", Expanded.ToString());

            if (Selected)
                output.AddAttribute("Selected", "true");

            if (NavigateUrl != String.Empty)
                output.AddAttribute("NavigateUrl", NavigateUrl);

            if (Checked)
                output.AddAttribute("Checked", "true");

            if (NodeData != String.Empty)
                output.AddAttribute("NodeData", NodeData);
            
            AddAttributesToRender(output);

            output.RenderBeginTag("tvns:treenode");

            if (Text != String.Empty)
                output.Write(Text);
    
            base.RenderUpLevelPath(output);

            // Render contained nodes
            foreach (TreeNode node in Nodes)
                node.Render(output, RenderPathID.UpLevelPath);

            output.RenderEndTag();             
        }
        
        /// <summary>
        /// Returns the node's previous TreeNode sibling, or null
        /// </summary>
        /// <returns>The node's previous TreeNode sibling, or null.</returns>
        protected TreeNode GetPreviousSibling()
        {
            TreeNodeCollection sibs;
            if (Parent is TreeNode)
                sibs = ((TreeNode)Parent).Nodes;
            else
                sibs = ((TreeView)Parent).Nodes;

            int iIndex = sibs.IndexOf(this) - 1;
            if (iIndex >= 0)
                return sibs[iIndex];
            else
                return null;
        }

        /// <summary>
        /// Returns a x.y.z format node index string representing the node's position in the hierarchy.
        /// </summary>
        /// <returns>The x.y.z formatted index.</returns>
        public string GetNodeIndex()
        {
            string strIndex = "";
            Object node = this;
            while (node is TreeNode)
            {
                if (((TreeNode)node).SibIndex == -1)
                    return String.Empty;
                if (strIndex.Length == 0)
                    strIndex = ((TreeNode)node).SibIndex.ToString();
                else
                    strIndex = ((TreeNode)node).SibIndex.ToString() + "." + strIndex;
                node = ((TreeNode)node).Parent;
            } 
            return strIndex;
        }

        /// <summary>
        /// Determine if the current node is an L, T, or Root junction.
        /// Note: This code is essentially duplicated from the client behavior.
        /// </summary>
        /// <returns>A character defining the type of junction.</returns>
        protected char CalcJunction()
        {
            if (Parent is TreeView && GetPreviousSibling() == null)
            {
                // Get index of node and add 1 to the last value
                string strIndex = GetNodeIndex();
                int iIndexPos = strIndex.LastIndexOf('.');
                int iIndexVal = Convert.ToInt32(strIndex.Substring(iIndexPos + 1)) + 1;
                strIndex = strIndex.Substring(0,iIndexPos + 1) + iIndexVal.ToString();
                // if the node exists, we're an "F" node.
                if (ParentTreeView.GetNodeFromIndex(strIndex) != null)
                    return 'F';
                else
                    return 'R';
            }
            else
            {
                TreeNodeCollection col;
                if (Parent is TreeView)
                    col = ((TreeView)Parent).Nodes;
                else
                    col = ((TreeNode)Parent).Nodes;
                int i = col.IndexOf(this) + 1;
                if (i < col.Count)
                    return 'T';
                return 'L';
            }
        }

        /// <summary>
        /// Renders the designer version of the TreeNode, which is the downlevel version.
        /// </summary>
        /// <param name="output">The HtmlTextWriter that will receive that markup.</param>
        protected override void RenderDesignerPath(HtmlTextWriter output)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?