TreeView.SelectedNode, when is it set???

Last post 02-23-2007 3:40 PM by Tomáš Studva. 3 replies.

Sort Posts:

  • TreeView.SelectedNode, when is it set???

    11-28-2006, 8:28 AM
    • Contributor
      3,298 point Contributor
    • Russ Helfand
    • Member since 09-14-2005, 6:22 PM
    • Groovybits.com
    • Posts 741

    Thomas from Germany has been helping spread the word that the adapters have hit RTM, http://blog.thomasbandt.de/de/aspnet/aspnet-2/aspnet-20-css-friendly-control-adapters-10.aspx.

    Unfortunately one of Thomas' readers encountered a problem:

    Albert Weinert meint: (23.11.2006 13:47:00)
    Leider ist das TreeView nicht zu gebrauchen, da die SelectedNode weg ist sobald ein Postback über was anderes als das TreeView ausgelöst wird. Problem ist bekannt, nicht behoben.

    Basically this reports that the SelectedNode property of the adapted TreeView control improperly is null in the Load event for the Page.

    I have confirmed this problem.  The TreeViewAdapter is not setting the value of the SelectedNode property until its override of the RaisePostBackEvent method is called. This may reveal a very simple workaround for many developers.  Let me explain.

    Install the latest (RTM) version of the adapter kit.  In Visual Studio, create a new web site using the template called ASP.NET CSS Friendly Web Site.  Replace the contents of WalkThru\SimpleTreeView.aspx with the following:

    <%@ Page Language="C#" %>

    <script runat="server">
        protected TreeNode FindSelectedNode(TreeNodeCollection nodes)
        {
            if (nodes != null)
            {
                foreach (TreeNode node in nodes)
                {
                    if (node.Selected)
                    {
                        return node;
                    }
                    TreeNode childNode = FindSelectedNode(node.ChildNodes);
                    if (childNode != null)
                    {
                        return childNode;
                    }
                }           
            }
            return null;
        }
       
        protected void FixTreeView(TreeView treeView)
        {
            if (treeView != null)
            {
                TreeNode selectedNode = FindSelectedNode(treeView.Nodes);
                if (selectedNode != null)
                {
                    selectedNode.Select();
                }
            }
        }
       
        public void Page_PreRender(Object sender, EventArgs e)
        {
            MessageLabel1.Text = EntertainmentTreeView.SelectedNode == null ? "Null" : EntertainmentTreeView.SelectedNode.Text;
            FixTreeView(EntertainmentTreeView);
            MessageLabel2.Text = EntertainmentTreeView.SelectedNode == null ? "Null" : EntertainmentTreeView.SelectedNode.Text;
        }
    </script>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <link rel="stylesheet" href="SimpleTreeView.css" type="text/css" />
        <link runat="server" rel="stylesheet" href="~/CSS/Import.css" type="text/css" id="AdaptersInvariantImportCSS" />
    <!--[if lt IE 7]>
        <link runat="server" rel="stylesheet" href="~/CSS/BrowserSpecific/IEMenu6.css" type="text/css" id="IEMenu6CSS" />
    <![endif]-->
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:TreeView ID="EntertainmentTreeView" runat="server" CssSelectorClass="SimpleEntertainmentTreeView" ExpandDepth="0">
                <Nodes>
                    <asp:TreeNode Text="Music" SelectAction="Expand">
                        <asp:TreeNode Text="Classical" />
                        <asp:TreeNode Text="Rock">
                            <asp:TreeNode Text="Electric" />
                            <asp:TreeNode Text="Acoustical" />
                        </asp:TreeNode>
                        <asp:TreeNode Text="Jazz" />
                    </asp:TreeNode>
                    <asp:TreeNode Text="Movies" SelectAction="Expand">
                        <asp:TreeNode Text="Action" />
                        <asp:TreeNode Text="Drama" />
                        <asp:TreeNode Text="Musical" />
                    </asp:TreeNode>
                </Nodes>
            </asp:TreeView>
           
            <div>
                <asp:Button runat="server" UseSubmitBehavior="true" Text="Submit" />
            </div>
           
            <div id="EntertainmentMessage">
                <asp:Label id="MessageLabel1" runat="server" />
                <br />
                <asp:Label id="MessageLabel2" runat="server" />
            </div>
        </form>
    </body>
    </html>

    There are a couple of things to note in this sample.  If you do things in Page_PreRender and you call FixTreeView then the TreeView's SelectedNode is correct.  That may provide some immediate relief for the problem.

    The real fix is probably to put something like FixTreeView into the adapter itself at the right point in its lifecycle.  That's going to take a little more work and thinking.  Can anyone confirm this workaround? Does anyone care to continue suggest where in the adapter's lifecycle we should do this fix-up?  Should we be handling SelectedNode in the TreeViewAdapter in a very different way?

    Russ Helfand
    Groovybits.com
  • Re: TreeView.SelectedNode, when is it set???

    11-29-2006, 4:22 AM

    Hello Russ,

    thank you for you help, but this workaround don't work. It works for the PreRender, but this is a much to late to normale Page LifeCycle.

    I try to describe the problem. On the Page is a TreeView and a Button, if i selected a Node in the TreeView then in the SelectedNodeChanged-Event then the SelectedNode is correct. Now i press the Button and within the the Click-Event the SelectedNode of the TreeView is null. But it is visualy selected in the TreeView. Sometimes after the Click-Event the Page.PreRender-Event is called, and this little "fix" manually set the selectedNode. After that everything is fine, but to late.

    In my case i can now "override" the SelectedNode property and call the recursive Search for getting the Node. But this seems not to be a good fix :)
     


  • Re: TreeView.SelectedNode, when is it set???

    01-03-2007, 1:47 PM

    Hi,

    I've encountered the same problem with SelectedNode == null. I think the presented workaround is ineffective, but working. The right place for FixTreeView() call is loadpostdata() in TreeAdapter.

    I have this scenario:

    tree is rendered, then by click node can be selected (page is postbacked) and later by another click(page is postbacked) the SelectedNode  is read.

    So it is important, that in every post back, the property SelectedNode is set and before onLoad. So there are two possibilities: in LoadViewState or LoadPostData. In LoadAdapterViewState() it doesn't works. In LoadPostData it is working.

    In original TreeView is used hidden field to store selected node index. And in loadpostdata, the index is used to select the node. The stored selected node index is TreeNode.Index - internal property. For performance reasons it could be done the same style - using hidden field.

     Tomas

     

  • Re: TreeView.SelectedNode, when is it set???

    02-23-2007, 3:40 PM
    A similiar bug (I think there is such bug, but don't know it for 100%) is with not raising selectedNodeChangedEvent. The workaround is same using fix treeview. The time to call must be before TreeViewAdapter.RaisePostBackEvent(). So appropriate time is as was said in method: TreeViewAdapter.LoadPostData().
Page 1 of 1 (4 items)