Disable Checkboxes in Treeview but keep them visible

25 posts, 2 answers
  1. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 24 Mar 2011 Link to this post

    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
  2. Answer
    Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 25 Mar 2011 Link to this post

    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
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 28 Mar 2011 Link to this post

    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
  5. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 28 Mar 2011 Link to this post

    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
  6. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 28 Mar 2011 Link to this post

    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);
            }
        }

     

  7. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    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
  8. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 29 Mar 2011 Link to this post

    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
  9. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    Hi Richard

    That would be brilliant.

    Thanks mate

    regards
    Ian
  10. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 29 Mar 2011 Link to this post

    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
  11. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    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

  12. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 29 Mar 2011 Link to this post

    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
  13. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 29 Mar 2011 Link to this post

    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
  14. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    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
  15. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 29 Mar 2011 Link to this post

    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
  16. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    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
  17. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 29 Mar 2011 Link to this post

    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
  18. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 30 Mar 2011 Link to this post

    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
  19. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 30 Mar 2011 Link to this post

    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
  20. Answer
    Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 30 Mar 2011 Link to this post

    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
  21. Ian
    Ian avatar
    61 posts
    Member since:
    Jul 2010

    Posted 30 Mar 2011 Link to this post

    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
  22. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 30 Mar 2011 Link to this post

    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
  23. Swati
    Swati avatar
    6 posts
    Member since:
    Aug 2011

    Posted 28 Aug 2012 Link to this post

    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...
  24. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 30 Aug 2012 Link to this post

    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
  25. Andrew
    Andrew avatar
    1 posts
    Member since:
    Oct 2011

    Posted 02 Aug 2013 Link to this post

    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.
  26. Stefan
    Admin
    Stefan avatar
    2891 posts

    Posted 05 Aug 2013 Link to this post

    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 >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready