TreeView adapter problems..

Rate It (2)

Last post 09-27-2006 4:49 PM by brian.brown. 1 replies.

Sort Posts:

  • TreeView adapter problems..

    09-27-2006, 2:00 PM
    • Member
      25 point Member
    • brian.brown
    • Member since 09-27-2006, 1:45 PM
    • Posts 5

    I have discovered several problems with the treeview adapter.

    First, NodeCheckChanged event is refired for every node that is checked in every postback.  I created a fix that involves creating a postbackeventreference in the BuildItem method of the TreeViewAdapter.cs file:

                    if (((item.ShowCheckBox != null) && (item.ShowCheckBox.Value == true)) ||
                        (treeView.ShowCheckBoxes == TreeNodeTypes.All) ||
                        ((treeView.ShowCheckBoxes == TreeNodeTypes.Leaf) && (!IsExpandable(item))) ||
                        ((treeView.ShowCheckBoxes == TreeNodeTypes.Parent) && (IsExpandable(item))) ||
                        ((treeView.ShowCheckBoxes == TreeNodeTypes.Root) && (item.Depth == 0)))
                    {
                        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 (item.Checked)
                        {
                            writer.WriteAttribute("checked", "checked");
                        }
                        // Add event for checkchanged
                        writer.WriteAttribute("onclick", Page.ClientScript.GetPostBackEventReference(treeView, "c" + (Page.Server.HtmlEncode(item.ValuePath)).Replace("/", "\\"), true));
                        writer.Write(HtmlTextWriter.SelfClosingTagEnd);
                        _checkboxIndex++;
                    }

     To capture the event, I added the following code to the RaisePostBackEvent:
     

    	if (eventArgument != null)
                    {
                        if (eventArgument.StartsWith("s") || eventArgument.StartsWith("e"))
                        {
                            string selectedNodeValuePath = eventArgument.Substring(1).Replace("\\", "/");
                            TreeNode selectedNode = treeView.FindNode(selectedNodeValuePath);
                            if (selectedNode != null)
                            {
                                bool bSelectedNodeChanged = selectedNode != treeView.SelectedNode;
                                selectedNode.Selected = true; // does not raise the SelectedNodeChanged event so we have to do it manually (below).
                                ExpandToSelectedNode();
                                if (eventArgument.StartsWith("e"))
                                {
                                    selectedNode.Expanded = true;
                                }
    
                                if (bSelectedNodeChanged)
                                {
                                    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)))
                            {
                                ExpandToNode(parentNode);
                                parentNode.Expanded = true; // Raises the TreeNodePopulate event
                            }
                        }
                        else if (eventArgument.StartsWith("c"))
                        {
                            string parentNodeValuePath = eventArgument.Substring(1).Replace("\\", "/");
                            TreeNode parentNode = treeView.FindNode(parentNodeValuePath);
                            if (parentNode != null)
                            {
                                Extender.RaiseAdaptedEvent("TreeNodeCheckChanged", new TreeNodeEventArgs(parentNode));
                            }
                        }

     I then commented out the the RaiseAdaptedEvent line in the UpdateCheckmarks method:
     
                            if (item.Checked != bIsNowChecked)
                            {
                                item.Checked = bIsNowChecked;
                                // Adding postback support for checkmarks
                                //Extender.RaiseAdaptedEvent("TreeNodeCheckChanged", new TreeNodeEventArgs(item));

                            }

     That line was the cause of the TreeNodeCheckChanged event firing for every checked node.

    The second problem I found is the TreeViewAdapter doesn't raise events properly if the treeview is in a webcontrol.  This is due to how the RaiseAdapterEvent was created.. 
     

            public void RaiseAdaptedEvent(string eventName, EventArgs e)
            {
                string attr = "OnAdapted" + eventName;
                if ((AdaptedControl != null) &&
                    (AdaptedControl.Attributes[attr] != null) &&
                    (AdaptedControl.Attributes[attr].Length > 0))
                {
                    string delegateName = AdaptedControl.Attributes[attr];
                    MethodInfo method = AdaptedControl.Page.GetType().GetMethod(delegateName);
                    if (method != null)
                    {
                        object[] args = new object[2];
                        args[0] = AdaptedControl;
                        args[1] = e;
                        method.Invoke(AdaptedControl.Page, args);
                    }
                }
            }
     The Page references cause the code to fail as the method delegate is in a control and not page.  I fixed this by changing the code to:
     
            public void RaiseAdaptedEvent(string eventName, EventArgs e)
            {
                string attr = "OnAdapted" + eventName;
                if ((AdaptedControl != null) &&
                    (AdaptedControl.Attributes[attr] != null) &&
                    (AdaptedControl.Attributes[attr].Length > 0))
                {
                    string delegateName = AdaptedControl.Attributes[attr];
                    MethodInfo method = AdaptedControl.Parent.GetType().GetMethod(delegateName);
                    if (method != null)
                    {
                        object[] args = new object[2];
                        args[0] = AdaptedControl;
                        args[1] = e;
                        method.Invoke(AdaptedControl.Parent, args);
                    }
                }
            }

     I did some basic testing and it looks like referencing the parent works a lot better than referencing the page.

    The last problem I have figured out yet..  but it is easy to reproduce.  I can't get nodes to expand in some of the demos.  For example go here:
    http://www.asp.net/CSSAdapters/TreeView.aspx
    Change the theme to 'Enhanced', then try to expand a node.  The nodes won't expand.

     

  • Re: TreeView adapter problems..

    09-27-2006, 4:49 PM
    Answer
    • Member
      25 point Member
    • brian.brown
    • Member since 09-27-2006, 1:45 PM
    • Posts 5
    Umm...  I posted this to the "CSS Friendly Control Adapters" on purpose.. it has nothing to do with the standard treeview.  Please move this post to the 'CSS Friendly Control Adapters' forum:  http://forums.asp.net/1018/ShowForum.aspx
Page 1 of 1 (2 items)