locked
Updated version of TreeView CSS adapter - Improved postback and state handling RRS feed

  • Question

  • User-327389586 posted
    /*
    I've rewritten some parts of the TreeView CSS adapter which wasn't consistent with the original treeview behaviour. 
    Especially the original postback handling had some serious issues, selectednode, and checked nodes are now fixed.
    Most of the changes has been to LoadPostData, RaisePostBackEvent, SaveAdapterViewState
     */ 
     
    using System;
    using System.Collections.Specialized;
    using System.Configuration;
    using System.Data;
    using System.Web;
    using System.Web.Configuration;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    
    using System.Reflection;
    using System.Text;
    
    namespace CSSFriendly
    {
        public class TreeViewAdapter : System.Web.UI.WebControls.Adapters.HierarchicalDataBoundControlAdapter, IPostBackEventHandler, IPostBackDataHandler
        {
            private WebControlAdapterExtender _extender = null;
            private WebControlAdapterExtender Extender
            {
                get
                {
                    if (((_extender == null) && (Control != null)) ||
                        ((_extender != null) && (Control != _extender.AdaptedControl)))
                    {
                        _extender = new WebControlAdapterExtender(Control);
                    }
    
                    System.Diagnostics.Debug.Assert(_extender != null, "CSS Friendly adapters internal error", "Null extender instance");
                    return _extender;
                }
            }
    
            private int _checkboxIndex = 1;
            private HiddenField _viewState = null;
            private bool _updateViewState = false; //Not neccesary, can be removed
            private string _newViewState = "";
    
            //Addition to preserve seletednodes and checkednodes state serverside
            private bool _selectedNodeChanged=false;
            private string[] _checkedNodes=null;
            private string _selectedNode=null;
    
    
            public TreeViewAdapter()
            {
                if (_viewState == null)
                {
                    _viewState = new HiddenField();
                }
            }
    
            // Implementation of IPostBackDataHandler
            public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
            {
                //Debug example {__VIEWSTATEGUID=e4eb4095-37d2-4364-84ca-89ba100701a8&__VIEWSTATE=&ctl11=ee&__EVENTTARGET=TreeView1&__EVENTARGUMENT=s3%5c3-1&__EVENTVALIDATION=%2fwEWCQL%2braDpAgLgg%2bMwAuCD5zACw%2baTwA0C4IPbMALD5vPjBALD5vfjBAKM54rGBgKiwPWxArcNRAdnn2j0PGOp9YF7d3%2bHhBjh}
    
                TreeView treeView = Control as TreeView;
    
                string eventTarget = postCollection["__EVENTTARGET"];
                string eventArgument=postCollection["__EVENTARGUMENT"];
    
                //**************** From loadViewState: Must be here because the nodes in treeView is not present at all times in loadadapterviewstate
                if (!String.IsNullOrEmpty(_selectedNode))
                {
                    TreeNode tn = treeView.FindNode(_selectedNode.Replace("|", "|"));
                    if (tn != null)
                        tn.Select();
                }
                if (_checkedNodes != null)
                {
                    foreach (string checkedNode in _checkedNodes)
                    {
                        TreeNode tn = treeView.FindNode(checkedNode.Replace(":", ":").Replace("|", "|"));
                        if (tn != null)
                            tn.Checked = true;
                    }
                }
                //**************** Stop ***********************************************************************************
    
                //**************** FROM onload: Must be here so its before form_load,  or we won't be able to check if the nodes are expanded in form_load
                if (Extender.AdapterEnabled && _updateViewState && (treeView != null))
                {
                    treeView.CollapseAll();
                    ExpandToState(treeView.Nodes, _newViewState);
                    _updateViewState = false;
                }
                //**************** Stop *********************************************************************************** 
    
                //**************** FROM RaisePostBackEvent: Must be here so its before form_load, or selected cant be determined at that point
                if ((treeView != null) && (eventTarget == Control.UniqueID)) //Control.ID out threeview has generated an event
                {
                    if (!String.IsNullOrEmpty(eventArgument))
                    {
                        if (eventArgument.StartsWith("s") || eventArgument.StartsWith("e"))
                        {
                            string selectedNodeValuePath = eventArgument.Substring(1).Replace("\\", "/");
                            TreeNode selectedNode = treeView.FindNode(selectedNodeValuePath);
                            if (selectedNode != null)
                            {
                                _selectedNodeChanged = selectedNode != treeView.SelectedNode;
                                ClearSelectedNode(treeView.Nodes);
                                selectedNode.Select();
    
                                if (eventArgument.StartsWith("e"))
                                {
                                    selectedNode.Expand();
                                }
                            }
                        }
                    }
                }
                //**************** Stop *********************************************************************************** 
                return true;
            }
    
            public virtual void RaisePostDataChangedEvent()
            {
                TreeView treeView = Control as TreeView;
                if (treeView != null)
                {
                    TreeNodeCollection items = treeView.Nodes;
                    _checkboxIndex = 1;
                    UpdateCheckmarks(items);
                }
            }
    
            // Implementation of IPostBackEventHandler
            public void RaisePostBackEvent(string eventArgument)
            {
                TreeView treeView = Control as TreeView;
                if (treeView != null)
                {
                    TreeNodeCollection items = treeView.Nodes;
                    if (!String.IsNullOrEmpty(eventArgument))
                    {
                        if (eventArgument.StartsWith("s") || eventArgument.StartsWith("e"))
                        {
                            if (_selectedNodeChanged)
                            {
                                Extender.RaiseAdaptedEvent("SelectedNodeChanged", new EventArgs());
                            }
                        }
                        else if (eventArgument.StartsWith("p"))
                        {
                            string parentNodeValuePath = eventArgument.Substring(1).Replace("\\", "/");
                            TreeNode parentNode = treeView.FindNode(parentNodeValuePath);
                            if ((parentNode != null) && ((parentNode.ChildNodes == null) || (parentNode.ChildNodes.Count == 0)))
                            {
                                parentNode.Expand(); // Raises the TreeNodePopulate event
                            }
                        }
                    }
                }
            }
    
            protected override Object SaveAdapterViewState()
            {
    
                string retStr = "";
                TreeView treeView = Control as TreeView;
                if ((treeView != null) && (_viewState != null))
                {
                    if ((_viewState != null) && (Page != null) && (Page.Form != null) && (!Page.Form.Controls.Contains(_viewState)))
                    {
                        Panel panel = new Panel();
                        panel.Controls.Add(_viewState);
                        Page.Form.Controls.Add(panel);
                        string script = "document.getElementById('" + _viewState.ClientID + "').value = GetViewState__AspNetTreeView('" + Extender.MakeChildId("UL") + "');";
                        Page.ClientScript.RegisterOnSubmitStatement(typeof(TreeViewAdapter), _viewState.ClientID, script);
                    }
                    //retStr = _viewState.UniqueID + "|" + ComposeViewState(treeView.Nodes, "");
                    //Serialize treeView attributes
                    StringBuilder ctn=new StringBuilder();
                    foreach (TreeNode tn in treeView.CheckedNodes)
                    {
                        ctn.Append(tn.ValuePath.Replace(":", ":").Replace("|","|"));
                        if (ctn.Length > 0)
                            ctn.Append(";");
                    }
                    string selectedNode = treeView.SelectedNode==null?"":treeView.SelectedNode.ValuePath.Replace("|", "|"); 
                    retStr = _viewState.UniqueID + "|" + ComposeViewState(treeView.Nodes, "") + "|" + ctn.ToString() + "|" + selectedNode ;
                }
                return retStr;
    
            }
            protected override void LoadAdapterViewState(Object state)
            {
                TreeView treeView = Control as TreeView;
                string oldViewState = state as String;
    
                string[] parameters = oldViewState.Split('|');
                if ((treeView != null) && (oldViewState != null) && (parameters.Length == 4))
                {
                    string hiddenInputName = parameters[0];
                    string oldExpansionState = parameters[1];
                    
                    //More viewstate data...
    
                    _checkedNodes = String.IsNullOrEmpty(parameters[2])?null:parameters[2].Split(':');
                    _selectedNode = parameters[3];
                    _selectedNodeChanged = false;
    
                    if (!treeView.ShowExpandCollapse)
                    {
                        _newViewState = oldExpansionState;
                        _updateViewState = true;
                    }
                    else if (!String.IsNullOrEmpty(Page.Request.Form[hiddenInputName]))
                    {
                        _newViewState = Page.Request.Form[hiddenInputName];
                        _updateViewState = true;
                    }
                
                }
    
            }
            protected override void OnInit(EventArgs e)
            {
                if (Extender.AdapterEnabled)
                {
                    _updateViewState = false;
                    _newViewState = "";
    
                    TreeView treeView = Control as TreeView;
                    if (treeView != null)
                    {
                        treeView.EnableClientScript = false;
                    }
                }
    
                base.OnInit(e);
    
                if (Extender.AdapterEnabled)
                {
                    RegisterScripts();
                }
            }
    
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
    
                 // This information should already be present before Page_Load so we have to move it into LoadPostData 
    /*  
                TreeView treeView = Control as TreeView;
                if (Extender.AdapterEnabled && _updateViewState && (treeView != null))
                {
                    treeView.CollapseAll();
                    ExpandToState(treeView.Nodes, _newViewState);
                    _updateViewState = false;
                }
      */          
            }
    
            private void RegisterScripts()
            {
                Extender.RegisterScripts();
                string folderPath = WebConfigurationManager.AppSettings.Get("CSSFriendly-JavaScript-Path");
                if (String.IsNullOrEmpty(folderPath))
                {
                    folderPath = "~/CSSAdapters/JavaScript";
                }
                string filePath = folderPath.EndsWith("/") ? folderPath + "TreeViewAdapter.js" : folderPath + "/TreeViewAdapter.js";
                Page.ClientScript.RegisterClientScriptInclude(GetType(), GetType().ToString(), Page.ResolveUrl(filePath));
            }
    
            protected override void RenderBeginTag(HtmlTextWriter writer)
            {
                if (Extender.AdapterEnabled)
                {
                    Extender.RenderBeginTag(writer, "AspNet-TreeView");
                }
                else
                {
                    base.RenderBeginTag(writer);
                }
            }
    
            protected override void RenderEndTag(HtmlTextWriter writer)
            {
                if (Extender.AdapterEnabled)
                {
                    Extender.RenderEndTag(writer);
                }
                else
                {
                    base.RenderEndTag(writer);
                }
            }
    
            protected override void RenderContents(HtmlTextWriter writer)
            {
                if (Extender.AdapterEnabled)
                {
                    TreeView treeView = Control as TreeView;
                    if (treeView != null)
                    {
                        writer.Indent++;
                        _checkboxIndex = 1;
                        BuildItems(treeView.Nodes, true, true, writer);
                        writer.Indent--;
                        writer.WriteLine();
                    }
                }
                else
                {
                    base.RenderContents(writer);
                }
            }
    
            private void BuildItems(TreeNodeCollection items, bool isRoot, bool isExpanded, HtmlTextWriter writer)
            {
                if (items.Count > 0)
                {
                    writer.WriteLine();
    
                    writer.WriteBeginTag("ul");
    
                    if (isRoot)
                    {
                        writer.WriteAttribute("id", Extender.MakeChildId("UL"));
                    }
                    if (!isExpanded)
                    {
                        writer.WriteAttribute("class", "AspNet-TreeView-Hide");
                    }
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Indent++;
    
                    foreach (TreeNode item in items)
                    {
                        BuildItem(item, writer);
                    }
    
                    writer.Indent--;
                    writer.WriteLine();
                    writer.WriteEndTag("ul");
                }
            }
    
            private void BuildItem(TreeNode item, HtmlTextWriter writer)
            {
                TreeView treeView = Control as TreeView;
                if ((treeView != null) && (item != null) && (writer != null))
                {
                    writer.WriteLine();
                    writer.WriteBeginTag("li");
                    writer.WriteAttribute("class", GetNodeClass(item));
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Indent++;
                    writer.WriteLine();
    
                    if (IsExpandable(item) && treeView.ShowExpandCollapse)
                    {
                        WriteNodeExpander(treeView, item, writer);
                    }
                    //ADDED option of both link and checkbox, which is allowed in a regular tree
                    if ((IsCheckbox(treeView,item)) && (IsLink(item)))
                    {
                        WriteNodeLinkCheckbox(treeView, item, writer);
                    }
                    else if (IsCheckbox(treeView, item))
                    {
                        WriteNodeCheckbox(treeView, item, writer);
                    }
                    else if (IsLink(item))
                    {
                        WriteNodeLink(treeView, item, writer);
                    }
                    else
                    {
                        WriteNodePlain(treeView, item, writer);
                    }
    
                    if (HasChildren(item))
                    {
                        BuildItems(item.ChildNodes, false, item.Expanded.Equals(true), writer);
                    }
    
                    writer.Indent--;
                    writer.WriteLine();
                    writer.WriteEndTag("li");
                }
            }
    
            private void WriteNodeExpander(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
                writer.WriteBeginTag("span");
                writer.WriteAttribute("class", (item.Expanded.Equals(true) ? "AspNet-TreeView-Collapse" : "AspNet-TreeView-Expand"));
                if (HasChildren(item))
                {
                    writer.WriteAttribute("onclick", "ExpandCollapse__AspNetTreeView(this)");
                }
                else
                {
                    writer.WriteAttribute("onclick", Page.ClientScript.GetPostBackEventReference(treeView, "p" + (Page.Server.HtmlEncode(item.ValuePath)).Replace("/", "\\"), true));
                }
                writer.Write(HtmlTextWriter.TagRightChar);
                writer.Write(" ");
                writer.WriteEndTag("span");
                writer.WriteLine();
            }
    
            private void WriteNodeImage(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
                string imgSrc = GetImageSrc(treeView, item);
                if (!String.IsNullOrEmpty(imgSrc))
                {
                    writer.WriteBeginTag("img");
                    writer.WriteAttribute("src", treeView.ResolveClientUrl(imgSrc));
                    writer.WriteAttribute("alt", !String.IsNullOrEmpty(item.ToolTip) ? item.ToolTip : (!String.IsNullOrEmpty(treeView.ToolTip) ? treeView.ToolTip : item.Text));
                    writer.Write(HtmlTextWriter.SelfClosingTagEnd);
                }
            }
    
            private void WriteNodeLinkCheckbox(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
    
                writer.WriteBeginTag("input");
                writer.WriteAttribute("type", "checkbox");
                writer.WriteAttribute("id", treeView.ClientID + "n" + _checkboxIndex.ToString() + "CheckBox");
                writer.WriteAttribute("name", treeView.UniqueID + "n" + _checkboxIndex.ToString() + "CheckBox");
    
                if (!String.IsNullOrEmpty(treeView.Attributes["OnClientClickedCheckbox"]))
                {
                    writer.WriteAttribute("onclick", treeView.Attributes["OnClientClickedCheckbox"]);
                }
    
                if (item.Checked)
                {
                    writer.WriteAttribute("checked", "checked");
                }
                writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    
                if (!String.IsNullOrEmpty(item.Text))
                {
    
                    WriteNodeLink(treeView,item, writer);
    
    /*
                    writer.WriteLine();
                    writer.WriteBeginTag("label");
                    writer.WriteAttribute("for", treeView.ClientID + "n" + _checkboxIndex.ToString() + "CheckBox");
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Write(item.Text);
                    writer.WriteEndTag("label");
     */ 
                }
    
                _checkboxIndex++;
            }
    
            private void WriteNodeCheckbox(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
                writer.WriteBeginTag("input");
                writer.WriteAttribute("type", "checkbox");
                writer.WriteAttribute("id", treeView.ClientID + "n" + _checkboxIndex.ToString() + "CheckBox");
                writer.WriteAttribute("name", treeView.UniqueID + "n" + _checkboxIndex.ToString() + "CheckBox");
    
                if (!String.IsNullOrEmpty(treeView.Attributes["OnClientClickedCheckbox"]))
                {
                    writer.WriteAttribute("onclick", treeView.Attributes["OnClientClickedCheckbox"]);
                }
    
                if (item.Checked)
                {
                    writer.WriteAttribute("checked", "checked");
                }
                writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    
                if (!String.IsNullOrEmpty(item.Text))
                {
                    writer.WriteLine();
                    writer.WriteBeginTag("label");
                    writer.WriteAttribute("for", treeView.ClientID + "n" + _checkboxIndex.ToString() + "CheckBox");
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Write(item.Text);
                    writer.WriteEndTag("label");
                }
    
                _checkboxIndex++;
            }
    
    
            private void WriteNodeLink(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
                writer.WriteBeginTag("a");
    
                if (!String.IsNullOrEmpty(item.NavigateUrl))
                {
                    writer.WriteAttribute("href", Extender.ResolveUrl(item.NavigateUrl));
                }
                else
                {
                    string codePrefix = "";
                    if (item.SelectAction == TreeNodeSelectAction.Select)
                    {
                        codePrefix = "s";
                    }
                    else if (item.SelectAction == TreeNodeSelectAction.SelectExpand)
                    {
                        codePrefix = "e";
                    }
                    else if (item.PopulateOnDemand)
                    {
                        codePrefix = "p";
                    }
                    writer.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(treeView, codePrefix + (Page.Server.HtmlEncode(item.ValuePath)).Replace("/", "\\"), true));
                }
    
                WebControlAdapterExtender.WriteTargetAttribute(writer, item.Target);
    
                if (!String.IsNullOrEmpty(item.ToolTip))
                {
                    writer.WriteAttribute("title", item.ToolTip);
                }
                else if (!String.IsNullOrEmpty(treeView.ToolTip))
                {
                    writer.WriteAttribute("title", treeView.ToolTip);
                }
                writer.Write(HtmlTextWriter.TagRightChar);
                writer.Indent++;
                writer.WriteLine();
    
                WriteNodeImage(treeView, item, writer);
                writer.Write(item.Text);
    
                writer.Indent--;
                writer.WriteEndTag("a");
            }
    
            private void WriteNodePlain(TreeView treeView, TreeNode item, HtmlTextWriter writer)
            {
                writer.WriteBeginTag("span");
                if (IsExpandable(item))
                {
                    writer.WriteAttribute("class", "AspNet-TreeView-ClickableNonLink");
                    if (treeView.ShowExpandCollapse)
                    {
                        writer.WriteAttribute("onclick", "ExpandCollapse__AspNetTreeView(this.parentNode.getElementsByTagName('span')[0])");
                    }
                }
                else
                {
                    writer.WriteAttribute("class", "AspNet-TreeView-NonLink");
                }
                writer.Write(HtmlTextWriter.TagRightChar);
                writer.Indent++;
                writer.WriteLine();
    
                WriteNodeImage(treeView, item, writer);
                writer.Write(item.Text);
    
                writer.Indent--;
                writer.WriteEndTag("span");
            }
    
            private void UpdateCheckmarks(TreeNodeCollection items)
            {
                TreeView treeView = Control as TreeView;
                if ((treeView != null) && (items != null))
                {
                    foreach (TreeNode item in items)
                    {
                        if (IsCheckbox(treeView, item))
                        {
                            string name = treeView.UniqueID + "n" + _checkboxIndex.ToString() + "CheckBox";
                            bool bIsNowChecked = (Page.Request.Form[name] != null);
                            if (item.Checked != bIsNowChecked)
                            {
                                item.Checked = bIsNowChecked;
                                Extender.RaiseAdaptedEvent("TreeNodeCheckChanged", new TreeNodeEventArgs(item));
                            }
                            _checkboxIndex++;
                        }
    
                        if (HasChildren(item))
                        {
                            UpdateCheckmarks(item.ChildNodes);
                        }
                    }
                }
            }
    
            private bool IsLink(TreeNode item)
            {
                return (item != null) && ((!String.IsNullOrEmpty(item.NavigateUrl)) || item.PopulateOnDemand || (item.SelectAction == TreeNodeSelectAction.Select) || (item.SelectAction == TreeNodeSelectAction.SelectExpand));
            }
    
            private bool IsCheckbox(TreeView treeView, TreeNode item)
            {
                bool bItemCheckBoxDisallowed = (item.ShowCheckBox != null) && (item.ShowCheckBox.Value == false);
                bool bItemCheckBoxWanted = (item.ShowCheckBox != null) && (item.ShowCheckBox.Value == true);
                bool bTreeCheckBoxWanted =
                     (treeView.ShowCheckBoxes == TreeNodeTypes.All) ||
                     ((treeView.ShowCheckBoxes == TreeNodeTypes.Leaf) && (!IsExpandable(item))) ||
                     ((treeView.ShowCheckBoxes == TreeNodeTypes.Parent) && (IsExpandable(item))) ||
                     ((treeView.ShowCheckBoxes == TreeNodeTypes.Root) && (item.Depth == 0));
    
                return (!bItemCheckBoxDisallowed) && (bItemCheckBoxWanted || bTreeCheckBoxWanted);
            }
    
            private string GetNodeClass(TreeNode item)
            {
                string value = "AspNet-TreeView-Leaf";
                if (item != null)
                {
                    if (item.Depth == 0)
                    {
                        if (IsExpandable(item))
                        {
                            value = "AspNet-TreeView-Root";
                        }
                        else
                        {
                            value = "AspNet-TreeView-Root AspNet-TreeView-Leaf";
                        }
                    }
                    else if (IsExpandable(item))
                    {
                        value = "AspNet-TreeView-Parent";
                    }
    
                    if (item.Selected)
                    {
                        value += " AspNet-TreeView-Selected";
                    }
                    else if (IsChildNodeSelected(item))
                    {
                        value += " AspNet-TreeView-ChildSelected";
                    }
                    else if (IsParentNodeSelected(item))
                    {
                        value += " AspNet-TreeView-ParentSelected";
                    }
                }
                return value;
            }
    
            private string GetImageSrc(TreeView treeView, TreeNode item)
            {
                string imgSrc = "";
    
                if ((treeView != null) && (item != null))
                {
                    imgSrc = item.ImageUrl;
    
                    if (String.IsNullOrEmpty(imgSrc))
                    {
                        if (item.Depth == 0)
                        {
                            if ((treeView.RootNodeStyle != null) && (!String.IsNullOrEmpty(treeView.RootNodeStyle.ImageUrl)))
                            {
                                imgSrc = treeView.RootNodeStyle.ImageUrl;
                            }
                        }
                        else
                        {
                            if (!IsExpandable(item))
                            {
                                if ((treeView.LeafNodeStyle != null) && (!String.IsNullOrEmpty(treeView.LeafNodeStyle.ImageUrl)))
                                {
                                    imgSrc = treeView.LeafNodeStyle.ImageUrl;
                                }
                            }
                            else if ((treeView.ParentNodeStyle != null) && (!String.IsNullOrEmpty(treeView.ParentNodeStyle.ImageUrl)))
                            {
                                imgSrc = treeView.ParentNodeStyle.ImageUrl;
                            }
                        }
                    }
    
                    if ((String.IsNullOrEmpty(imgSrc)) && (treeView.LevelStyles != null) && (treeView.LevelStyles.Count > item.Depth))
                    {
                        if (!String.IsNullOrEmpty(treeView.LevelStyles[item.Depth].ImageUrl))
                        {
                            imgSrc = treeView.LevelStyles[item.Depth].ImageUrl;
                        }
                    }
                }
    
                return imgSrc;
            }
    
            private bool HasChildren(TreeNode item)
            {
                return ((item != null) && ((item.ChildNodes != null) && (item.ChildNodes.Count > 0)));
            }
    
            private bool IsExpandable(TreeNode item)
            {
                return (HasChildren(item) || ((item != null) && item.PopulateOnDemand));
            }
    
            private void ClearSelectedNode(TreeNodeCollection nodes)
            {
                if (nodes != null)
                {
                    foreach (TreeNode node in nodes)
                    {
                        if (node.Selected)
                        {
                            node.Selected = false;
                        }
                        if (node.ChildNodes != null)
                        {
                            ClearSelectedNode(node.ChildNodes);
                        }
                    }
                }
            }
    
            private bool IsChildNodeSelected(TreeNode item)
            {
                bool bRet = false;
    
                if ((item != null) && (item.ChildNodes != null))
                {
                    bRet = IsChildNodeSelected(item.ChildNodes);
                }
    
                return bRet;
            }
    
            private bool IsChildNodeSelected(TreeNodeCollection nodes)
            {
                bool bRet = false;
    
                if (nodes != null)
                {
                    foreach (TreeNode node in nodes)
                    {
                        if (node.Selected || IsChildNodeSelected(node.ChildNodes))
                        {
                            bRet = true;
                            break;
                        }
                    }
                }
    
                return bRet;
            }
    
            private bool IsParentNodeSelected(TreeNode item)
            {
                bool bRet = false;
    
                if ((item != null) && (item.Parent != null))
                {
                    if (item.Parent.Selected)
                    {
                        bRet = true;
                    }
                    else
                    {
                        bRet = IsParentNodeSelected(item.Parent);
                    }
                }
    
                return bRet;
            }
    
            private string ComposeViewState(TreeNodeCollection nodes, string state)
            {
                if (nodes != null)
                {
                    foreach (TreeNode node in nodes)
                    {
                        if (IsExpandable(node))
                        {
                            if (node.Expanded.Equals(true))
                            {
                                state += "e";
                                state = ComposeViewState(node.ChildNodes, state);
                            }
                            else
                            {
                                state += "n";
                            }
                        }
                    }
                }
    
                return state;
            }
    
            private string ExpandToState(TreeNodeCollection nodes, string state)
            {
                if ((nodes != null) && (!String.IsNullOrEmpty(state)))
                {
                    foreach (TreeNode node in nodes)
                    {
                        if (IsExpandable(node))
                        {
                            bool bExpand = (state[0] == 'e');
                            state = state.Substring(1);
                            if (bExpand)
                            {
                                node.Expand();
                                state = ExpandToState(node.ChildNodes, state);
                            }
                        }
                    }
                }
    
                return state;
            }
    
            static public void ExpandToDepth(TreeNodeCollection nodes, int expandDepth)
            {
                if (nodes != null)
                {
                    foreach (TreeNode node in nodes)
                    {
                        if (node.Depth < expandDepth)
                        {
                            node.Expand();
                            ExpandToDepth(node.ChildNodes, expandDepth);
                        }
                    }
                }
            }
    
        }
    }
    
     
     
     
     

     

    Friday, April 27, 2007 8:04 AM

All replies

  • User-348520086 posted

    Wow!  I wish I had found this 3 days ago! Thank you so much!

     

    This is AWESOME!

    Wednesday, September 19, 2007 1:23 PM
  • User-534534125 posted

    Hi

    I tried what you suggested, namely:

    1. I downloaded the source code (CSSFriendly_1.0.zip) from http://www.codeplex.com/cssfriendly/
    2. I opened the project with VS2005, opened file TreeViewAdapter.cs and pasted the code you posted
    3. I recompiled the project and tried to use it in an existing project.

    Results where:

    1. On IE7, I got bullets on my TreeView - as if embedded css wasn't setup correctly
    2. On Firefox, the tree displays correctly, however when you try to do something with it you get 'GetViewState__AspNetTreeView is not defined' as if embedded javascript wasn't setup correctly

    Any suggestions?

    Friday, December 7, 2007 11:58 AM
  • User-534534125 posted

    Ok I've got it, seems the code posted above was intended for the non-embedded approach.

    If using the newer embedded approach (i.e. you only use the .dll and .browser files) just replace RegisterScript() method from above code with newer version:

     

    private void RegisterScripts()
    {
    	Extender.RegisterScripts();
    
    	/* 
    	 * Modified for support of compiled CSSFriendly assembly
    	 * 
    	 * We will first search for embedded JavaScript files. If they are not
    	 * found, we default to the standard approach.
    	 */
    
    	Type type = this.GetType();
    
    	// TreeViewAdapter.js
    	string resource = "CSSFriendly.JavaScript.TreeViewAdapter.js";
    	string filePath = Page.ClientScript.GetWebResourceUrl(type, resource);
    
    	// if filePath is empty, use the old approach
    	if(String.IsNullOrEmpty(filePath))
    	{
    		string folderPath = WebConfigurationManager.AppSettings.Get("CSSFriendly-JavaScript-Path");
    		if(String.IsNullOrEmpty(folderPath))
    		{
    			folderPath = "~/JavaScript";
    		}
    		filePath = folderPath.EndsWith("/") ? folderPath + "TreeViewAdapter.js" : folderPath + "/TreeViewAdapter.js";
    	}
    
    	if(!Page.ClientScript.IsClientScriptIncludeRegistered(type, resource))
    		Page.ClientScript.RegisterClientScriptInclude(type, resource, Page.ResolveUrl(filePath));
    
    	// TreeView.css -- only add if it is embedded
    	resource = "CSSFriendly.CSS.TreeView.css";
    	filePath = Page.ClientScript.GetWebResourceUrl(type, resource);
    
    	// if filePath is not empty, embedded CSS exists -- register it
    	if(!String.IsNullOrEmpty(filePath))
    	{
    		string cssTag = "&lt;link href=\"" + Page.ResolveUrl(filePath) + "\" type=\"text/css\" rel=\"stylesheet\"&gt;</link>";
    		if(!Page.ClientScript.IsClientScriptBlockRegistered(type, resource))
    			Page.ClientScript.RegisterClientScriptBlock(type, resource, cssTag, false);
    	}
    }
    
     
    Friday, December 7, 2007 2:13 PM
  • User2098176964 posted

    Hi balleklorin

    Is ther any chance to get it in VB, And what is it about the green sections?
    I've tried rewrite the Csharp code but gets stuck on some parts, but I'm not that good with Csharp, for example:

    protected override void OnInit(EventArgs e)
            {
                if (Extender.AdapterEnabled)
                {
                    _updateViewState = False
                    _NewViewState = ""
     
                    Dim treeView As TreeView =  Control as TreeView
                    if (treeView <> Nothing)
                    {
                        treeView.EnableClientScript = False
                    }
                }
     
                MyBase.OnInit(e)
     
                if (Extender.AdapterEnabled)
                {
                    RegisterScripts()
                }
            }

     

    Thanks

    Sunday, December 9, 2007 2:41 PM
  • User-1016919829 posted

    I'm a convert to these CSS adapters as well, but alas I cannot get the TreeView adapter SelectedNodeChanged event to work (at least like a normal TreeView).

     In design mode I double click the control, I'm dropped into my code page on the Protected sub TreeView_SelectedNodeChanged (handles TreeView.SelectedNodeChanged) - but this event never fires when using the CSS TreeView adapter.

     Unless I've missed something, I assume it's a bug (pity), so I'm also hoping the above code will be released in VB so it might hopefully fix my problem.

      (Please tell me if I'm barking up the wrong tree here...)

     

    Wednesday, December 12, 2007 8:35 PM
  • User-534534125 posted

    Hi

    Try using OnAdaptedSelectedNodeChanged event as well. I use both events, pointing them to the same method like so:

    <asp:TreeView ID="MyTreeView" runat="server" 
        OnSelectedNodeChanged="MyTreeView_SelectedNodeChanged"
        OnAdaptedSelectedNodeChanged="MyTreeView_SelectedNodeChanged">
    </asp:TreeView>

     Note that your event handler must be public so it can be accessed by the adapter:

     

    Public Sub MyTreeView_SelectedNodeChanged(Object sender, EventArgs e)
        ...
    End Sub
    
      

    Finally, why are you guys waiting for the code to be released in VB? Why not download the source project, replace the relevant code as instructed on this post, compile the project and use the .DLL in your VB.NET project?

    Thursday, December 13, 2007 5:46 AM
  • User-1016919829 posted

    I'm not using the DLL method to use these controls - just a method I found in a book... thanks for the info, I'll look into the DLL method & give a recompile a go like you said...

     

    1st I'll try the OnAdaptedSelectedNodeChanged event... I'll also check if my handler is public....

    Friday, December 14, 2007 8:07 PM
  • User-1016919829 posted

    Spot on ppoulos... my event was declared as Private, making it Public & adding the OnAdaptedSelectedNodeChanged allowed me to get the event.. thank you!!!

    Friday, December 14, 2007 8:17 PM