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

Disable Checkboxes in Treeview but keep them visible

24 Answers 1963 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Ian
Top achievements
Rank 1
Ian asked on 25 Mar 2011, 03:14 AM
Hi Guys

I recently added a radiobutton element to the standard RadComboBoxItem by overriding the CreateChildElements() method on the control.

I was wondering if there was an override on the RadTreeNode which I could use to disable the checkbox which displays on a Node. I want the user to be able to see the checked state without being able to change it? Could I add a method to an inherited node which would allow me to use code like this.  

RadCustomTreeNode.Checkbox.Enabled = false;"

Many thanks in advance

Regards
Ian Carson

24 Answers, 1 is accepted

Sort by
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 25 Mar 2011, 11:00 AM
Hello,

In Q1 2011 the RadTreeView has been given a major overhaul and now uses the TPF which means it is fully customizable. Just like the RadGridView's well known CellFormatting event, you can perform similar operations in the RadTreeView.

The new RadTreeView contains a NodeFormatting event where you can perform this functionality. For exmaple

private void radTreeView1_NodeFormatting(object sender, TreeNodeFormattingEventArgs e)
{
    ((TreeNodeCheckBoxElement)e.NodeElement.Children[2]).Enabled = false;
}

I hope this helps but let me know if you have further questions
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 28 Mar 2011, 09:34 AM
Hello,

Did this help? If so, please remember to mark as answer. If you need further assistance though, do just let me know.
Thanks
Richard
0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 12:43 AM
Hi Richard,

This was exactly what I needed thanks.

Now I'm  having a go at adding a second checkbox to the treenode. Any hints as to the best way to do this?

Regards
Ian
0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 03:26 AM
Hi Richard

This what I have so far. The code below gets a checkbox onto the node at the beginning of the text element of each node but it overwrites the Text element. I have attached a screenshot of the outcome as well.

Can you see where I am going awry?

Called the CreateNodeElement event on the treeview

void TreeViewElement_CreateNodeElement(object sender, CreateTreeNodeElementEventArgs e)       
{           
      e.NodeElement = new RadCustomTreeNodeElementWithExtraCheckBox();   
}

This is the RadCustomTreeNodeElementWithExtraCheckBox Class

 

public class RadCustomTreeNodeElementWithExtraCheckBox: TreeNodeElement
    {
        protected override void InitializeFields() 
        
            base.InitializeFields(); 
            this.StretchHorizontally = false;
            this.StretchVertically = false;
        }
  
        protected override TreeNodeContentElement CreateContentElement()
        {
            return new RadCustomContentElement();
        }   
          
        protected override Type ThemeEffectiveType 
        
            get {return typeof(TreeNodeElement);} 
        }
    }

And this is the RadCustomContentElement class

public class RadCustomContentElement:TreeNodeContentElement
    {
        TreeNodeCheckBoxElement chkBox2;
        TreeNodeElement treenodeElement;
        protected override Type ThemeEffectiveType 
        
            get {return typeof(TreeNodeContentElement);} 
        }
  
        protected override void InitializeFields()
        {
            base.InitializeFields();
        }
  
        public override void Synchronize()
        {
            base.Synchronize();
            treenodeElement = this.NodeElement;
            RadTreeNode node = treenodeElement.Data;
        }
  
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
            chkBox2 = new TreeNodeCheckBoxElement();
            chkBox2.Margin = new Padding(0, 0, 5, 0);
            chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
            base.Children.Add(chkBox2);
        }
    }

 

0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 08:07 AM
Hi Again Richard

Due to the time difference between Australia and Boston I continue to make progress while you sleep!

I realised I was creating the checkbox in the Content element and have now corrected this so that the RadCustomTreeNodeElementWithExtraCheckBox Class now creates the checkbox element inside the treeNode Element as follows:

public
class RadCustomTreeNodeElementWithExtraCheckBox: TreeNodeElement
    {
        TreeNodeCheckBoxElement chkBox2;
        protected override void InitializeFields() 
        
            base.InitializeFields(); 
            this.StretchHorizontally = false;
            this.StretchVertically = false;
        }
  
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
            chkBox2 = new TreeNodeCheckBoxElement();
            chkBox2.ToggleStateChanged += new StateChangedEventHandler(chkBox2_ToggleStateChanged);
            chkBox2.Click += new EventHandler(chkBox2_Click);
            //chkBox2.Margin = new Padding(0, 0, 5, 0);
            chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
            Children.Insert(1, chkBox2);
        }
  
        void chkBox2_Click(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
  
        void chkBox2_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            throw new NotImplementedException();
        }
          
        protected override Type ThemeEffectiveType 
        {
            get { return typeof(TreeNodeElement); } 
        }
    }
 
You'll notice from the above that I'm now struggling with the positioning of the checkbox in the treenode stack . I want it to be the first item in the node but the separation between the new checkbox and the rest of the node is now too large. It looks like the treeview has been set right-to-left but I have done nothing deliberate to make this happen. See attached file.

I also need to know how I trap the new node's "CheckChanged" event as an event on the node so that when the new checkbox is checked/unchecked I have something like a second "NodeCheckChanged" event to use on the node

All help gratefully received! :-)

Thanks in advance

Regards
Ian
0
Richard Slade
Top achievements
Rank 2
answered on 29 Mar 2011, 11:09 AM
Hi Ian,

I'll see if I can prepare a sample for you as soon as I can. Hope it will be today.
Regards,
Richard
0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 11:11 AM
Hi Richard

That would be brilliant.

Thanks mate

regards
Ian
0
Richard Slade
Top achievements
Rank 2
answered on 29 Mar 2011, 12:14 PM
Hi Ian,

I think this will get you started.
From my understanding so far of thew new RadTreeView, you will need to create the additional checkbox as content. The node content will contain the checkbox and a new text element (I hide the node text, so we can display the context correctly). If you want the additional checkbox to be the first one, then you'd need to create two checkbox elements in the context and hide the original node checkbox.

At the moment though, I've turned on standard checkboxes and created one additional checkbox and textelement which should guide you in the right direction.

Designer File
namespace RadControlsWinFormsApp1
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components;
  
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
  
        #region Windows Form Designer generated code
  
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.radTreeView1 = new Telerik.WinControls.UI.RadTreeView();
            ((System.ComponentModel.ISupportInitialize)(this.radTreeView1)).BeginInit();
            this.SuspendLayout();
            // 
            // radTreeView1
            // 
            this.radTreeView1.BackColor = System.Drawing.SystemColors.Control;
            this.radTreeView1.Cursor = System.Windows.Forms.Cursors.Default;
            this.radTreeView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.radTreeView1.Font = new System.Drawing.Font("Segoe UI", 8.25F);
            this.radTreeView1.ForeColor = System.Drawing.Color.Black;
            this.radTreeView1.Location = new System.Drawing.Point(0, 0);
            this.radTreeView1.Name = "radTreeView1";
            this.radTreeView1.RightToLeft = System.Windows.Forms.RightToLeft.No;
            // 
            // 
            // 
            this.radTreeView1.RootElement.ForeColor = System.Drawing.Color.Black;
            this.radTreeView1.Size = new System.Drawing.Size(359, 342);
            this.radTreeView1.TabIndex = 0;
            this.radTreeView1.Text = "radTreeView1";
            this.radTreeView1.NodeCheckedChanged += new Telerik.WinControls.UI.RadTreeView.TreeViewEventHandler(this.radTreeView1_NodeCheckedChanged);
            this.radTreeView1.CreateNodeElement += new Telerik.WinControls.UI.CreateTreeNodeElementEventHandler(this.radTreeView1_CreateNodeElement);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(359, 342);
            this.Controls.Add(this.radTreeView1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.radTreeView1)).EndInit();
            this.ResumeLayout(false);
  
        }
  
        #endregion
  
        private Telerik.WinControls.UI.RadTreeView radTreeView1;
  
    }
}

Form1.cs
#region Using Statements
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Telerik.WinControls;
using System.Drawing.Drawing2D;
using Telerik.WinControls.Primitives;
#endregion
  
namespace RadControlsWinFormsApp1
{
    public partial class Form1 : Form
    {
  
        #region Ctor
        public Form1()
        {
            InitializeComponent();
            this.radTreeView1.CheckBoxes = true;
  
            DataTable table = new DataTable();
            table.Columns.Add("Id", typeof(int));
            table.Columns.Add("ParentId", typeof(int));
            table.Columns.Add("Dosage", typeof(int));
            table.Columns.Add("Drug", typeof(string));
  
            table.Rows.Add(1, 0, 25, "Indocin");
            table.Rows.Add(2, 0, 50, "Enebrel");
            table.Rows.Add(3, 1, 10, "Hydralazine");
            table.Rows.Add(4, 2, 21, "Combivent");
            table.Rows.Add(5, 1, 100, "Dilantin");
  
            this.radTreeView1.DisplayMember = "Drug";
            this.radTreeView1.ChildMember = "Id";
            this.radTreeView1.ParentMember = "ParentId";
            this.radTreeView1.DataSource = table;
            this.radTreeView1.ExpandAll();
        }
        #endregion
  
        #region Create Node Element
        private void radTreeView1_CreateNodeElement(object sender, Telerik.WinControls.UI.CreateTreeNodeElementEventArgs e)
        {
            e.NodeElement = new RadCustomTreeNodeElementWithExtraCheckBox();
        }
        #endregion
  
        private void radTreeView1_NodeCheckedChanged(object sender, RadTreeViewEventArgs e)
        {
            MessageBox.Show(e.Node.Text + " (primary check) " + e.Node.CheckState.ToString());
        }
  
    }
  
    public class RadCustomTreeNodeElementWithExtraCheckBox : TreeNodeElement
    {
        protected override void InitializeFields()
        {
            base.InitializeFields();
            this.StretchHorizontally = false;
            this.StretchVertically = false; ;
        }
  
        protected override TreeNodeContentElement CreateContentElement()
        {
            return new RadCustomContentElement();
        }
  
        protected override Type ThemeEffectiveType
        {
            get { return typeof(TreeNodeElement); }
        }
    }
  
    public class RadCustomContentElement : TreeNodeContentElement
    {
        TreeNodeCheckBoxElement checkElement;
        LightVisualElement textElement;
        TreeNodeElement treenodeElement;
  
        protected override Type ThemeEffectiveType
        {
            get { return typeof(TreeNodeContentElement); }
        }
  
        protected override void InitializeFields()
        {
            base.InitializeFields();
        }
  
        public override void Synchronize()
        {
            base.Synchronize();
            treenodeElement = this.NodeElement;
            textElement.Text = treenodeElement.Data.Text;
  
            this.DrawText = false;
            this.DrawFill = false;
            this.DrawBorder = false;
        }
  
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
  
            // add the text element
            textElement = new LightVisualElement();
            this.textElement.Padding = new Padding(20, 0, 0, 0);
            this.textElement.TextAlignment = ContentAlignment.TopLeft;
            this.Children.Add(textElement);
  
            // add the checkbox element
            checkElement = new TreeNodeCheckBoxElement();
            this.checkElement.Padding = new Padding(0, 0, 0, 0);
            this.checkElement.ToggleStateChanged += new StateChangedEventHandler(checkElement_ToggleStateChanged);
            this.Children.Add(checkElement);
        }
  
        void checkElement_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            MessageBox.Show(this.textElement.Text + " (additional check) " + args.ToggleState.ToString());
        }
  
  
    }
}

Hope that helps
Richard
0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 01:22 PM
Hi Richard

Thanks for your quick reply. I've had a go with your suggested approach but unfortunately overriding CreateChildElements within the Content Element ties the action of the new checkbox to the click event on the Content element and I need that event elsewhere in my solution.

I can create the checkbox with an independent action if I override CreateChildElements in the RadCustomTreeNodeElementWithExtraCheckBox Class as follows. This produces the result in the attached file.

public class RadCustomTreeNodeElementWithExtraCheckBox: TreeNodeElement
    {
        TreeNodeCheckBoxElement chkBox2;
        protected override void InitializeFields() 
        
            base.InitializeFields(); 
            this.StretchHorizontally = false;
            this.StretchVertically = false;
        }
  
  
        public override void Synchronize()
        {
            base.Synchronize();
  
        }
  
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
  
            chkBox2 = new TreeNodeCheckBoxElement();
            chkBox2.Padding = new Padding(0, 0, 0, 0);
            chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
            this.chkBox2.ToggleStateChanged += new StateChangedEventHandler(chkBox2_ToggleStateChanged);
            this.Children.Insert(2, chkBox2);
            base.UpdateLayout();
        }
  
        void chkBox2_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            MessageBox.Show( " (additional check) " + args.ToggleState.ToString());
  
        }
          
        protected override Type ThemeEffectiveType 
        {
            get { return typeof(TreeNodeElement); } 
        }
    }

This is great as far as it goes but I'm still uncertain on two matters

  • How I get the ToggleStateChanged event on the checkbox to raise a NodeCheckChanged event specific to the new checkbox on the node itself. I need this as I am managing a particular system setting based on the existing NodeCheckChanged and need another NodeCheckChanged to allow me to access Node properties during the event as part of the another setting's management.

 

  • Why the layout of the Content elements is skewed to the right. I've tried turning righttoleft to "No" but this has had no effect. I have also tried capturing the RighttoLeft Changing event and resetting to "No" if Yes" was the value but this has not worked either.

 

Your thoughts would be much appreciated.

Regards
Ian

0
Richard Slade
Top achievements
Rank 2
answered on 29 Mar 2011, 01:38 PM
Hello Ian,

Perhaps this will help you whilst I look at the remainder of your questions... (brings the text in line correctly)
protected override void CreateChildElements()
{
    base.CreateChildElements();
    chkBox2 = new TreeNodeCheckBoxElement();
    chkBox2.Padding = new Padding(0, 0, 0, 0);
    chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
    chkBox2.StretchHorizontally = false; // it was strethched....
    this.chkBox2.ToggleStateChanged += new StateChangedEventHandler(chkBox2_ToggleStateChanged);
    this.Children.Insert(2, chkBox2);
    base.UpdateLayout();
}

Will try and get back to you shortly with other answers
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 29 Mar 2011, 03:07 PM
Hi Again,

Ok, I think this will do what you need. I have made an inherited RadTreeView that raises an additional event for the new checkbox.

Form1.Designer.cs
namespace RadControlsWinFormsApp1
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components;
  
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
  
        #region Windows Form Designer generated code
  
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.radTreeViewTwoCheckBoxes1 = new RadTreeViewTwoCheckBoxes();
            ((System.ComponentModel.ISupportInitialize)(this.radTreeViewTwoCheckBoxes1)).BeginInit();
            this.SuspendLayout();
            // 
            // radTreeViewTwoCheckBoxes1
            // 
            this.radTreeViewTwoCheckBoxes1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.radTreeViewTwoCheckBoxes1.Location = new System.Drawing.Point(0, 0);
            this.radTreeViewTwoCheckBoxes1.Name = "radTreeViewTwoCheckBoxes1";
            this.radTreeViewTwoCheckBoxes1.Size = new System.Drawing.Size(359, 342);
            this.radTreeViewTwoCheckBoxes1.TabIndex = 0;
            this.radTreeViewTwoCheckBoxes1.Text = "radTreeViewTwoCheckBoxes1";
            this.radTreeViewTwoCheckBoxes1.AdditionaNodeCheckedChanged += new AdditionalNodeCheckedChangedHandler(this.radTreeViewTwoCheckBoxes1_AdditionaNodeCheckedChanged);
            this.radTreeViewTwoCheckBoxes1.NodeCheckedChanged += new Telerik.WinControls.UI.RadTreeView.TreeViewEventHandler(this.radTreeViewTwoCheckBoxes1_NodeCheckedChanged);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(359, 342);
            this.Controls.Add(this.radTreeViewTwoCheckBoxes1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.radTreeViewTwoCheckBoxes1)).EndInit();
            this.ResumeLayout(false);
  
        }
  
        #endregion
  
        private RadTreeViewTwoCheckBoxes radTreeViewTwoCheckBoxes1;
  
  
  
    }
}

Form1.cs
#region Using Statements
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Telerik.WinControls;
using System.Drawing.Drawing2D;
using Telerik.WinControls.Primitives;
#endregion
  
namespace RadControlsWinFormsApp1
{
    public partial class Form1 : Form
    {
  
        #region Ctor
        public Form1()
        {
            InitializeComponent();
            this.radTreeViewTwoCheckBoxes1.CheckBoxes = true;
  
            DataTable table = new DataTable();
            table.Columns.Add("Id", typeof(int));
            table.Columns.Add("ParentId", typeof(int));
            table.Columns.Add("Dosage", typeof(int));
            table.Columns.Add("Drug", typeof(string));
  
            table.Rows.Add(1, 0, 25, "Indocin");
            table.Rows.Add(2, 0, 50, "Enebrel");
            table.Rows.Add(3, 1, 10, "Hydralazine");
            table.Rows.Add(4, 2, 21, "Combivent");
            table.Rows.Add(5, 1, 100, "Dilantin");
  
            this.radTreeViewTwoCheckBoxes1.DisplayMember = "Drug";
            this.radTreeViewTwoCheckBoxes1.ChildMember = "Id";
            this.radTreeViewTwoCheckBoxes1.ParentMember = "ParentId";
            this.radTreeViewTwoCheckBoxes1.DataSource = table;
            this.radTreeViewTwoCheckBoxes1.ExpandAll();
        }
        #endregion
  
        private void radTreeViewTwoCheckBoxes1_AdditionaNodeCheckedChanged(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e)
        {
            MessageBox.Show(e.Node.Text + " (additional) " + e.AdditionalCheckboxToggleState.ToString());
        }
  
        private void radTreeViewTwoCheckBoxes1_NodeCheckedChanged(object sender, RadTreeViewEventArgs e)
        {
            MessageBox.Show(e.Node.Text + " (primary) " + e.Node.CheckState.ToString());
        }
    }
  
  
}

RadTreeViewTwoCheckboxes.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Drawing2D;
using Telerik.WinControls.UI;
using System.Windows.Forms;
  
  
    public delegate void AdditionalElementNodeCheckedChangedHandler(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e);
    public delegate void AdditionalNodeCheckedChangedHandler(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e);
  
    class RadTreeViewTwoCheckBoxes : RadTreeView
    {
        public event AdditionalNodeCheckedChangedHandler AdditionaNodeCheckedChanged; 
  
        public RadTreeViewTwoCheckBoxes()
        {
            base.CreateNodeElement += new CreateTreeNodeElementEventHandler(RadTreeViewTwoCheckBoxes_CreateNodeElement);
        }
  
        void RadTreeViewTwoCheckBoxes_CreateNodeElement(object sender, CreateTreeNodeElementEventArgs e)
        {
            e.NodeElement = new RadCustomTreeNodeElementWithExtraCheckBox();
            RadCustomTreeNodeElementWithExtraCheckBox element = (RadCustomTreeNodeElementWithExtraCheckBox)e.NodeElement;
            element.AdditionalElementNodeCheckedChanged += new AdditionalElementNodeCheckedChangedHandler(element_AdditionalNodeCheckedChanged);
        }
  
        void element_AdditionalNodeCheckedChanged(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e)
        {
            if (AdditionaNodeCheckedChanged != null)
            {AdditionaNodeCheckedChanged(sender, e); }
        }
  
        public override string ThemeClassName
        {
            get
            {
                return typeof(RadTreeView).FullName;
            }
            set
            {}
        }
  
        private class RadCustomTreeNodeElementWithExtraCheckBox : TreeNodeElement
        {
            public event AdditionalElementNodeCheckedChangedHandler AdditionalElementNodeCheckedChanged; 
            TreeNodeCheckBoxElement chkBox2;
  
  
            protected override void InitializeFields()
            {
                base.InitializeFields();
                this.StretchHorizontally = false;
                this.StretchVertically = false;
            }
  
  
            public override void Synchronize()
            {
                base.Synchronize();
  
            }
  
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
  
                chkBox2 = new TreeNodeCheckBoxElement();
                chkBox2.Padding = new Padding(0, 0, 0, 0);
                chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
                chkBox2.StretchHorizontally = false;
                this.chkBox2.ToggleStateChanged += new StateChangedEventHandler(chkBox2_ToggleStateChanged);
                this.Children.Insert(2, chkBox2);
                base.UpdateLayout();
            }
  
            void chkBox2_ToggleStateChanged(object sender, StateChangedEventArgs args)
            {
                AdditionalElementNodeCheckedChanged(sender, new AdditionalNodeCheckboxCheckedChangedEventArgs(this.Data, args.ToggleState));
            }
  
            protected override Type ThemeEffectiveType
            {
                get { return typeof(TreeNodeElement); }
            }
        }
  
    }

AdditionalNodeCheckedChangedEventArgs.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.WinControls.UI;
using Telerik.WinControls.Enumerations;
  
public class AdditionalNodeCheckboxCheckedChangedEventArgs : EventArgs
{
  
        public AdditionalNodeCheckboxCheckedChangedEventArgs(RadTreeNode node, ToggleState state)
        {
            this.Node = node;
            this.AdditionalCheckboxToggleState = state;
        }
  
        public RadTreeNode Node
        { get; set; }
  
        public ToggleState AdditionalCheckboxToggleState
        { get; set; }
}


it could probably do with a bit of tidying up, but I think it's basically all there.

Hope this helps
Richard
0
Ian
Top achievements
Rank 1
answered on 29 Mar 2011, 09:42 PM
Hi Richard,

Apologies for the delay but I had to go to bed at some point last night.

Many, many thanks for your great code. I now have a working additional checkbox and access to all the necessary properties to manage the system settings I was discussing in earlier posts.

In appreciation

Regards
Ian
0
Richard Slade
Top achievements
Rank 2
answered on 29 Mar 2011, 10:27 PM
Hi Ian,

Very glad I could be of help. It was interesting to do and to work with the newly released RadTreeView.

All the best
Richard
0
Ian
Top achievements
Rank 1
answered on 30 Mar 2011, 01:24 AM
Hi Richard

Now that I have a better grip on the structure of the childern in the nodes it is proving to be a very flexible addition to our solution.

Thanks again

Regards
Ian
0
Ian
Top achievements
Rank 1
answered on 30 Mar 2011, 03:29 AM

Hi Richard

I modified the AdditionalNodeCheckboxCheckedChangedEventArgs class to include the treeNodeElement as I needed to access the other children of the element. The args look like this now:

public class AdditionalNodeCheckboxCheckedChangedEventArgs : EventArgs
{
    public AdditionalNodeCheckboxCheckedChangedEventArgs(RadTreeNode node, TreeNodeElement nodeElement, ToggleState state)
    {
        this.Node = node;
        this.NodeElement = nodeElement;
        this.AdditionalCheckboxToggleState = state;
    }
    public RadTreeNode Node
    { get; set; }
    public ToggleState AdditionalCheckboxToggleState
    { get; set; }
    public TreeNodeElement NodeElement
    { get; set; }
}
  And the call in the RadCustome TreeView looks like this

public delegate void AdditionalElementNodeCheckedChangedHandler(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e);
    public delegate void AdditionalNodeCheckedChangedHandler(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e);
  
    public class RadCustomTreeView : RadTreeView
    {
        public event AdditionalNodeCheckedChangedHandler AdditionaNodeCheckedChanged;
  
        public RadCustomTreeView()
        {
            base.CreateNodeElement += new CreateTreeNodeElementEventHandler(RadCustomTreeView_CreateNodeElement);
        }
  
        void RadCustomTreeView_CreateNodeElement(object sender, CreateTreeNodeElementEventArgs e)
        {
            e.NodeElement = new RadCustomTreeNodeElementWithExtraCheckBox();
            RadCustomTreeNodeElementWithExtraCheckBox element = (RadCustomTreeNodeElementWithExtraCheckBox)e.NodeElement;
            element.AdditionalElementNodeCheckedChanged += new AdditionalElementNodeCheckedChangedHandler(element_AdditionalNodeCheckedChanged);
        }
  
        void element_AdditionalNodeCheckedChanged(object sender, AdditionalNodeCheckboxCheckedChangedEventArgs e)
        {
            if (AdditionaNodeCheckedChanged != null)
            { AdditionaNodeCheckedChanged(sender, e); }
        }
  
        public override string ThemeClassName
        {
            get
            {
                return typeof(RadTreeView).FullName;
            }
            set
            { }
        }
  
        private class RadCustomTreeNodeElementWithExtraCheckBox : TreeNodeElement
        {
            public event AdditionalElementNodeCheckedChangedHandler AdditionalElementNodeCheckedChanged;
            TreeNodeCheckBoxElement chkBox2;
  
  
            protected override void InitializeFields()
            {
                base.InitializeFields();
                this.StretchHorizontally = false;
                this.StretchVertically = false;
            }
  
  
            public override void Synchronize()
            {
                base.Synchronize();
  
            }
  
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
  
                chkBox2 = new TreeNodeCheckBoxElement();
                chkBox2.Padding = new Padding(5, 0, 5, 0);
                chkBox2.SmoothingMode = SmoothingMode.AntiAlias;
                chkBox2.CheckMarkPrimitive.CheckElement.ForeColor = Color.Red;
                chkBox2.StretchHorizontally = false;
                this.chkBox2.ToggleStateChanged += new StateChangedEventHandler(chkBox2_ToggleStateChanged);
                this.Children.Insert(2, chkBox2);
                base.UpdateLayout();
            }
  
            void chkBox2_ToggleStateChanged(object sender, StateChangedEventArgs args)
            {
                AdditionalElementNodeCheckedChanged(sender, new AdditionalNodeCheckboxCheckedChangedEventArgs(this.Data, this, args.ToggleState));
            }
  
            protected override Type ThemeEffectiveType
            {
                get { return typeof(TreeNodeElement); }
            }
        }
  
    }


Other users trying to solve similar problems may find this extra information useful. How the final version looks is in the attached file

Regards
Ian
0
Richard Slade
Top achievements
Rank 2
answered on 30 Mar 2011, 09:21 AM
Hi Ian,

I guess you're sleeping now...but just for as a note, you could actually do away with the Node in the EventArgs as the NodeElement.Data property is the node itself.  Perhaps you want to keep it though for readability.

Let me know if there's anything further you need
Richard
0
Ian
Top achievements
Rank 1
answered on 30 Mar 2011, 10:50 AM
Hi Richard

Understand your comment but will probably keep Node for now.

I have another little problem if you'd like to have a think about it?

I'm using a context menu (activated on a right click ) to allow the user to automatically check all the standard checkboxes as well as  all the additonal checkboxes we added. The NodeMouseDown event args only expose the Node and not the NodeElement so I was wondering how I might be able to reference the NodeElement child which is the additonal checkbox in order to examine and set its ToggleState? Am I being stupid? I think its been a long day.

Hope you understand this ramble. :-)

Regards
Ian
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 30 Mar 2011, 11:56 AM
Hi Ian,

There are probably other ways to do this, but this seems to be quite a quick way.

1: In the Form (where you want to check all the checkboxes) call:
this.radTreeViewTwoCheckBoxes1.CheckAll();

2: In the RadTreeViewTwoCheckBoxes class
a: Add a private list of all the node elements
private List<TreeNodeElement> nodeElements = new List<TreeNodeElement>();

b: Alter the CreateNodeElement to add each element to the List.
void RadTreeViewTwoCheckBoxes_CreateNodeElement(object sender, CreateTreeNodeElementEventArgs e)
{
    e.NodeElement = new RadCustomTreeNodeElementWithExtraCheckBox();
    RadCustomTreeNodeElementWithExtraCheckBox element = (RadCustomTreeNodeElementWithExtraCheckBox)e.NodeElement;
    element.AdditionalElementNodeCheckedChanged += new AdditionalElementNodeCheckedChangedHandler(element_AdditionalNodeCheckedChanged);
    nodeElements.Add(element);
}

c: Provide a CheckAll method to check all the nodes, and additional checkboxes in the treeview
public void CheckAll()
{
    for (int i = 0; i <= this.nodeElements.Count-1; i++)
    {
        ((TreeNodeCheckBoxElement)this.nodeElements[i].Children[3]).Checked = true;
        ((TreeNodeCheckBoxElement)this.nodeElements[i].Children[2]).Checked = true;
    }
}

Hope that this helps.
All the best
Richard

EDIT// Adding small video demo
0
Ian
Top achievements
Rank 1
answered on 30 Mar 2011, 01:35 PM
Hi Richard

Once again...brilliant. Your concept of the List being created at the time of element creation led me to a solution. I needed to be able to set the checked values by subtree i.e the rightclicked node and its child nodes. To keep track of the nodes into which the elements were created I used a dictionary instead of a list as follows

private Dictionary<RadCustomTreeNode, TreeNodeElement> nodeElements = new Dictionary<RadCustomTreeNode, TreeNodeElement>();


nodeElements.Add((RadCustomTreeNode)e.Node,element);


I then created a Method on the CustomTreeView to change the Togglestate of a node element's TreeNodeCheckBoxElement - but only that element which matched a node in the dictionary passed to the method

public void NodeExecuteToggleOn(RadCustomTreeNode node)
{
    TreeNodeElement value;
    if (nodeElements.TryGetValue(node, out value))
    {
        ((TreeNodeCheckBoxElement)value.Children[2]).ToggleState = ToggleState.On;
        nodeElements[node] = value;
    }
      


Then in my main form I run the following methods. The first method handles the click event from the context menu item while the second runs through the subtree under the clicked node changing the togglestates as required.

void rmiExecuteAllCheckboxes_Click(object sender, EventArgs e)
{
    tvAlphaWorkspace.NodeExecuteToggleOn(workspaceContextNode);
    TreeNodeRecursiveExecuteAll(workspaceContextNode.Nodes);
}
private void TreeNodeRecursiveExecuteAll(RadTreeNodeCollection nodes)
{
    foreach (RadCustomTreeNode myNode in nodes)
    {
        tvAlphaWorkspace.NodeExecuteToggleOn(myNode);
        TreeNodeRecursiveExecuteAll(myNode.Nodes);
    }
}


Quite neat and tidy!

Many thanks for kicking me off in the right direction.

regards
Ian
0
Richard Slade
Top achievements
Rank 2
answered on 30 Mar 2011, 01:41 PM
Hi Ian,

Again, glad that I could be of some help. As I mentioned, there may be other ways to achieve this via custom nodes or similar, but I think the solution you have is very usable.

Just a couple of other things, if this helped, may I ask that you also mark as answer, and also if you have further questions that are on a different topic to the original question, then please could you post these in a new forum thread so others can quickly find answers to the topic described in the title.

Thanks for letting me know your progress and results.
All the best
Richard
0
Swati
Top achievements
Rank 1
answered on 28 Aug 2012, 02:38 PM
Can you please tell me when is the RadFormatting event fires...I mean if i want to disable check boxes for sub Folders if main Folders is checked..then How to use RadFormatting event for disabling checkboxes...
0
Jack
Telerik team
answered on 30 Aug 2012, 12:25 PM
Hello Swati,

Thank you for writing.

The formatting events are fired constantly when a visual update is needed. Here is how you can disable the child nodes check boxes if the parent node check box is checked:
void radTreeView1_NodeFormatting(object sender, TreeNodeFormattingEventArgs e)
{
    if (e.Node.Parent != null && e.Node.Parent.Checked)
    {
        e.NodeElement.ToggleElement.Enabled = false;
    }
    else
    {
        e.NodeElement.ToggleElement.Enabled = true;
    }
}


I hope this helps.
 
Best wishes,
Jack
the Telerik team
0
Andrew
Top achievements
Rank 1
answered on 02 Aug 2013, 10:14 AM
Hello

I need this feature: "Disable Checkboxes in Treeview but keep them visible" in my Silverlight control.
Unfortunately, Silverlight version doesn't expose NodeFormatting event.

Thanks.
0
Stefan
Telerik team
answered on 05 Aug 2013, 11:00 AM
Hi Andrew,

This forum concerns RadControls for WinForms, while your question is about RadControls for Silverlight. Please address it in the appropriate forums so you can get adequate response: http://www.telerik.com/community/forums/silverlight/treeview.aspx.

 

Regards,
Stefan
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
Treeview
Asked by
Ian
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Ian
Top achievements
Rank 1
Swati
Top achievements
Rank 1
Jack
Telerik team
Andrew
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or