Uncategorized

HoverNodeStyle not applied with partial postback

The TreeView control has built-in Ajax capabilities when it comes to dynamically fill it nodes; this is done through the PopulateNodesFromClient:

Sometimes, it is not practical to statically predefine the tree structure due to data size or custom content that depends on user input. Because of this, the TreeView control supports dynamic node population. When the PopulateOnDemand property for a node is set to true, that node gets populated at run time when the node is expanded.

In addition to populating nodes on demand, it is possible to populate the nodes directly on a supported client browser. When the PopulateNodesFromClient property is set to true, a service is called from the client to populate the tree nodes, which eliminates the need to post back to the server. Otherwise, the TreeView control posts back to the server to populate the nodes.

The EnableClientScript property must also be set to true in order for the PopulateNodesFromClient property to be set to true.

Here’s the sample page:

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

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    public void PopulateNode(Object sender, TreeNodeEventArgs e) {
        for (int i = 0; i <= 5; i++) {
            TreeNode newNode = new TreeNode("Node number " + i.ToString());
            newNode.PopulateOnDemand = true;
            e.Node.ChildNodes.Add(newNode);
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
    <title></title>
    <style.customNodeColor{color:GreenYellow !important}</style> </head> <body>
        <form id="form1" runat="server">
            <div>
                <asp:TreeView ID="TreeView1" runat="server" PopulateNodesFromClient="true"
                    OnTreeNodePopulate="PopulateNode" ExpandDepth="1">
                    <Nodes>
                        <asp:TreeNode Text="Root" Value="Root">
                            <asp:TreeNode PopulateOnDemand="True" Text="First node" Value="First node"></asp:TreeNode>
                            <asp:TreeNode PopulateOnDemand="True" Text="Second node" Value="Second node"></asp:TreeNode>
                            <asp:TreeNode PopulateOnDemand="True" Text="Third node" Value="Third node"></asp:TreeNode>
                            <asp:TreeNode PopulateOnDemand="True" Text="Fourth node" Value="Fourth node"></asp:TreeNode>
                        </asp:TreeNode>
                    </Nodes>
                    <NodeStyle Font-Names="Arial" Font-Size="8pt" ForeColor="DarkBlue" HorizontalPadding="5" />
                    <RootNodeStyle Font-Bold="True" Font-Size="9pt" />
                    <HoverNodeStyle Font-Underline="True" ForeColor="Red" Font-Bold="true" CssClass="customNodeColor" />
                </asp:TreeView>
            </div>
        </form>
        </body>
</html>

Anyway there is a problem: if you run the page you’ll see the ForeColor defined for HoverNodeStyle works as expected (the text turns red)

first node
first node

But if you expand one of the nodes clicking on the “+” sign, something weird happens:

node 0
node 0

As you can see, the sub nodes (added dynamically) do not turn red as they should, but only the underlining color changes… Important to note: the problem reproduces only if we click on the “+” sign to expand the node; this triggers a partial (Ajax like) postback, but if we click on the node name, by default we have a full page postback and the problem does not reproduce anymore. Why?

According to the documentation, the value defined for HoverNodeStyle has precedence over other settings inherited from styles at higher levels:

Common settings usually include a custom background color, foreground color, font properties, and node spacing. Style properties are applied in the following order:
1. NodeStyle
2. RootNodeStyleParentNodeStyle, or LeafNodeStyle, depending on the node type. If the LevelStyles collection is defined, it is applied at this time, overriding the other node style properties
3. SelectedNodeStyle
4.HoverNodeStyle
The style settings for the HoverNodeStyle property override any corresponding node style settings that are in the NodeStyle, RootNodeStyle, ParentNodeStyle, LeafNodeStyle, or SelectedNodeStyle property

Uhm… that doe not seem to be the case. Really? Are you sure? ?

Take a closer look at the second screenshot above, the one where the mouse pointer is over the “Node number 0” sub node: who has the eagle eye? ?

The text is bold, and the bold style is defined only in HoverNodeStyle element; so this means the style is actually applied… Another thing: if we remove the FontColor element from NodeStyle, then the FontColor defined in HoverNodeStyle works as expected also with the partial postback! . So properties defined with the same name (we have FontColor both in NodeStyle and HoverNodeStyle) show the problem, while properties added at the lower level work fine.

This means only one thing: when we have a partial postback the style properties are applied in the wrong order.

So, do we have a solution? Of course… ?

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
        public void PopulateNode(Object sender, TreeNodeEventArgs e)
        {
            for (int i = 0; i <= 5; i++)
            {
                TreeNode newNode = new TreeNode("Node number " + i.ToString());
                newNode.PopulateOnDemand = true;
                e.Node.ChildNodes.Add(newNode);
            }
        }
</script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <style> .customNodeColor { color:GreenYellow !important } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:TreeView ID="TreeView1" runat="server" PopulateNodesFromClient="true" OnTreeNodePopulate="PopulateNode" ExpandDepth="1"> <Nodes> <asp:TreeNode Text="Root" Value="Root"> <asp:TreeNode PopulateOnDemand="True" Text="First node" Value="First node"></asp:TreeNode> <asp:TreeNode PopulateOnDemand="True" Text="Second node" Value="Second node"></asp:TreeNode> <asp:TreeNode PopulateOnDemand="True" Text="Third node" Value="Third node"></asp:TreeNode> <asp:TreeNode PopulateOnDemand="True" Text="Fourth node" Value="Fourth node"></asp:TreeNode> </asp:TreeNode> </Nodes> <NodeStyle Font-Names="Arial" Font-Size="8pt" ForeColor="DarkBlue" HorizontalPadding="5" /> <RootNodeStyle Font-Bold="True" Font-Size="9pt" /> <HoverNodeStyle Font-Underline="True" ForeColor="Red" Font-Bold="true" CssClass="customNodeColor" /> </asp:TreeView> </div> </form> </body> </html>

Note the use of !important to assure the style is not overridden; here is the result:

first node styled
first node styled

Now also on sub node with partial postback we have the desired style:

first node styled
first node styled
Winking smile

As of today, I’m still discussing this issue internally, as soon as I’ll have any news (if this will be recognized as a bug, if there will be a fix etc…) I’ll update the post .

Update (12 January, 2009):

The solution above works fine on IE7 and IE8, but not IE6… for the latter, all the formatting must be applied through the CSS stylesheet with the !important attribute, as follows:

<style>
      .customNodeColor 
      {
             color:GreenYellow !important;
             text-decoration: underline !important;
      }
</style>

Carlo

Quote of the day:

There is always a well-known solution to every human problem: neat, plausible, and wrong – H. L. Mencken

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.