This is a migrated thread and some comments may be shown as answers.

Making the TreeViewNode's fore- and back-colours !important

9 Answers 199 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Stuart Hemming
Top achievements
Rank 2
Stuart Hemming asked on 31 Aug 2010, 10:40 AM
I have a bit of a strange situation wherein I need to set the CssClass of the nodes I'm creating and I need to set the fore- and background colours.

I need to set the CssClass to override the visual hovered and selected class effects. Basically, I need to make it look as if you can't click on certain nodes (I've already dealt with the JS side so actually clicking on the node does nothing).

At the same time I need to colour each node according to same data values.

The problem I have is that the CssClass I'm using to prevent the hover/select effects showing need to have both the foreground and background colours defined using the !important modifier and this overrides the colour settings added in the style attribute when the node renders. I need to have the node's color and background-color values rendered with the !important modifier.

I know I'm asking have my cake and eat it, but if it is at all possible to manage this, I'd appreciate a pointer.

-- 
Stuart

9 Answers, 1 is accepted

Sort by
0
Kamen Bundev
Telerik team
answered on 02 Sep 2010, 04:15 PM
Hi Stuart,

I'm not sure I completely understand what you are trying to do. Can you send some markup or a project where we can reproduce it in order to help you? Thank you in advance.

Kind regards,
Kamen Bundev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 06 Sep 2010, 11:19 AM
Kamen,

OK, let's simplify the problem.

Create a page as follows...
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs" Inherits="Default4" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1"
              runat="server">
            <telerik:RadScriptManager ID="RadScriptManager1"
                                      runat="server">
            </telerik:RadScriptManager>
            <telerik:RadScriptBlock ID="RadScriptBlock1"
                                    runat="server">
                    <script type="text/javascript">
                        function RadTreeView2NodeClicking(sender, e)
                            {
                        if (e.get_node().get_category() == "noselect")
                    {
                    e.set_cancel(true);
                    }
                    }
                </script>
            </telerik:RadScriptBlock>
     
            <div>
                <telerik:RadTreeView ID="RadTreeView1"
                                     runat="server"
                                     Skin="WebBlue"
                                     CheckBoxes="True"
                                     CheckChildNodes="true"
                                     TriStateCheckBoxes="true"
                                     DataTextField="Name"
                                     OnNodeDataBound="TreeView_NodeDataBound">
                </telerik:RadTreeView>
         
                <telerik:RadTreeView ID="RadTreeView2"
                                     runat="server"
                                     Skin="WebBlue"
                                     CheckBoxes="True"
                                     CheckChildNodes="true"
                                     TriStateCheckBoxes="true"
                                     OnClientNodeClicking="RadTreeView2NodeClicking"
                                     OnNodeDataBound="TreeView_NodeDataBound">
                </telerik:RadTreeView>
            </div>
        </form>
    </body>
</html>
using System;
using System.Collections.Generic;
using Telerik.Web.UI;
 
public partial class Default4 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RadTreeView1.DataSource = new List<NodeData> { new NodeData { Name = "Out-of-the-box TreeView" } };
        RadTreeView1.DataBind();
 
        RadTreeView2.DataSource = new List<NodeData> { new NodeData { Name = "TreeView with noselect on root node" } };
        RadTreeView2.DataBind();
 
    }
    protected void TreeView_NodeDataBound(object sender, RadTreeNodeEventArgs e)
    {
        RadTreeNode node = e.Node;
 
        node.Expanded = true;
        node.Category = "noselect";
        node.ForeColor = System.Drawing.Color.Red;
        node.BackColor = System.Drawing.Color.Yellow;
        for (int i = 1; i < 4; i++)
        {
            node.Nodes.Add(new RadTreeNode(String.Format("Child Node {0}", i)));
        }
 
    }
}
 
public class NodeData
{
    public string Name { get; set; }
}

Run the page and you'll have 2 TreeViews and the root node of each will be yellow with red text.

I need to be able to create a node, coloured like the root nodes in my example, but make them visually unselectable. The user needs to see the node as enabled and must be able to use the checkbox.

You'll see that the root node on the 2nd TreeView is, in fact, unselectable because I'm cancelling the NodeClick event. However, it's still highlighted as a clickable node when you mouse over.

In the past, I've got round this by adding a CssClass to these unselectable nodes hut now I need to decorate the nodes in the NodeDataBound event, just using a class that sets the background to white and the colour to black isn't going to cut it.

So to the question.

How can I arrange things in the 2nd TreeView so that the root node doesn't get highlighted when I mouse over, whilst at the same time:
  • Keeping the node enabled
  • Allowing the checkbox to be accessed
  • keeping the colour/background of the node.

Does that make the situation clearer?

-- 
Stuart
0
Peter
Telerik team
answered on 09 Sep 2010, 11:51 AM

Thanks for the additional info and code sample. One solution is to set the CssClass property and use it to overwrite the hover state of the target item. For example:
protected void TreeView_NodeDataBound(object sender, RadTreeNodeEventArgs e)
  {
      RadTreeNode node = e.Node;
      node.Expanded = true;
      node.Category = "noselect";
      node.ForeColor = System.Drawing.Color.Red;
      node.BackColor = System.Drawing.Color.Yellow;
      node.CssClass = "target";

.target:hover
 {
     background:yellow !important;    
     border: 1px solid transparent !important;
 }

I hope this works well at your side.


Greetings,
Peter
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 09 Sep 2010, 01:54 PM
Sadly, whilst that would work in my sample it won't in my real app as the fore- and background-colour are data-dependent. :-)

-- 
Stuart
0
Peter
Telerik team
answered on 14 Sep 2010, 02:56 PM

I will think of a workaround and follow up if I can come up with something. Apologies for not being able to help you at this point.


Greetings,
Peter
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 14 Sep 2010, 02:58 PM
Peter,

I appreciate the help. This one's got me scratching my head.

-- 
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 16 Sep 2010, 12:26 AM
Peter, 

Your original reply prompted a though in me; what if I created the CSS classes I need on the fly?

The following code provides a simple demonstration of how I achieved my desired goal.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs" Inherits="Default4" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1"
              runat="server">
            <telerik:RadScriptManager ID="RadScriptManager1"
                                      runat="server">
            </telerik:RadScriptManager>
            <telerik:RadScriptBlock ID="RadScriptBlock1"
                                    runat="server">
                <script type="text/javascript">
                    function RadTreeView2NodeClicking(sender, e)
                    {
                        if (e.get_node().get_category() == "noselect")
                        {
                            e.set_cancel(true);
                        }
                    }
                </script>
            </telerik:RadScriptBlock>
     
            <div>    
                <telerik:RadTreeView ID="RadTreeView2"
                                     runat="server"
                                     Skin="WebBlue"
                                     CheckBoxes="True"
                                     CheckChildNodes="true"
                                     TriStateCheckBoxes="true"
                                     OnClientNodeClicking="RadTreeView2NodeClicking"
                                     OnNodeDataBound="TreeView_NodeDataBound">
                </telerik:RadTreeView>
            </div>
        </form>
    </body>
</html>
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System;
using Telerik.Web.UI;
 
public partial class Default4 : System.Web.UI.Page
{
    int ClassCounter = 0;
    StringBuilder CssFiles = new StringBuilder();
 
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        Literal l = new Literal();
        l.Text = String.Format("<style type='text/css'>.RadTreeView .rtHover .rtIn {{padding: 4px 3px 3px !important;}}{0}</style>", CssFiles.ToString());
        Page.Header.Controls.Add(l);
    }
 
    protected void Page_Load(object sender, EventArgs e)
    {
        RadTreeView2.DataSource = new List<NodeData>{
            new NodeData{ Name = "root node 1", Foreground = "White", Background = "Black" },
            new NodeData{ Name = "root node 2", Foreground = "Orange", Background = "Yellow" },
            new NodeData{ Name = "root node 3", Foreground = "Black", Background = "Red" },
        };
        RadTreeView2.DataBind();
    }
 
    protected void TreeView_NodeDataBound(object sender, RadTreeNodeEventArgs e)
    {
        RadTreeNode node = e.Node;
 
        NodeData dataItem = node.DataItem as NodeData;
        node.Text = dataItem.Name;
        node.Expanded = true;
        node.Category = "noselect";
        string classID = String.Format("nodeClass{0}", ClassCounter++);
        node.CssClass = classID;
        CreateCssClass(classID, dataItem.Foreground, dataItem.Background);
        for (int i = 1; i < 3; i++)
        {
            node.Nodes.Add(new RadTreeNode(String.Format("Child Node {0}", i)));
        }
    }
 
    void CreateCssClass(string ClassID, string Foreground, string Background)
    {
        CssFiles.AppendLine(String.Format(".{0} {{color:{1} !important; background:{2} !important; border: 1px solid transparent !important; }}", ClassID, Foreground, Background));
    }
}
 
public class NodeData
{
    public string Background { get; set; }
 
    public string Foreground { get; set; }
 
    public string Name { get; set; }
}

As you can see, I'm creating each CssClass as I need it in the method CreateCssClass() and I'm passing the values I need in the NodeDataBound event.

The set of dynamically created CSS classes are added to the page's <head> tag in the PreRender stage. You'll prolly notice that I'm overriding a telerik supplied class at this point too. This is 'cos, by default, the skins change the padding of a node slightly when the node is hovered over, and whilst it's not really noticeable with the highlighting working as normal, it is visually quite jarring when the highlighting is disabled.

Anyway, if anyone can think of a better way of doing this, I'd be delighted to hear about it.

--
Stuart 
0
Accepted
Kamen Bundev
Telerik team
answered on 17 Sep 2010, 02:27 PM
Hello Stuart,

I think using a single CssClass and this rule should be enough for you to be able to set your colors from code behind:
div.RadTreeView .target,
div.RadTreeView .rtHover .target,
div.RadTreeView .rtSelected .target
{
     background: transparent;
     border: 0;
     padding: 4px 3px 3px;
}


Let me know if this works.

Sincerely yours,
Kamen Bundev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 17 Sep 2010, 07:06 PM
Kamen,

you're bang on.

Nice one,

-- 
Stuart
Tags
TreeView
Asked by
Stuart Hemming
Top achievements
Rank 2
Answers by
Kamen Bundev
Telerik team
Stuart Hemming
Top achievements
Rank 2
Peter
Telerik team
Share this question
or