Click here to Skip to main content
13,766,364 members
Click here to Skip to main content
Add your own
alternative version


109 bookmarked
Posted 10 Oct 2003
Licenced CPOL

XP theme aware TreeView control which supports checkbox and radio button nodes.

, 10 Oct 2003
Rate this:
Please Sign up or sign in to vote.
Internet Explorer advanced settings tree view clone. Supports checkbox and radio button nodes.


This tree view control is able to visualize checkbox and radio buttons, like the one you can find under Internet Explorer settings advanced tab. After Spy++ told me that Microsoft uses a normal tree view control, I fired up my Studio to write my own C# control clone named TreeViewRadioBox.

TreeViewRadioBoxReflection works a bit like the PropertyGrid. The public read and writeable properties of type bool and enum are fetched (reflection) and displayed as checkboxes and radio buttons, grouped by their category attribute. The properties' values are automatically updated if you edit the value in the tree view.



I tried to meet the following requirements / key features

  • Derived from System.Windows.Forms.TreeView class
  • Tree nodes are managed in collections
  • XP theme aware checkbox and radio button images, even if you switch theme at run time
  • TreeView familiar handling in general

No requirements without problems to solve

  • You can’t derive from TreeNodeCollection, internal constructor
  • How to draw the checkbox and radio button images, is it possible to draw on an image surface with GDI+
  • How to use the XP theme API

I guess there are many ways to visualize checkboxes and radio buttons mixed in a tree view. My solution was to use images which reflect the possible states of the two control types.

The main work was to imitate the behavior of the control types and switch the images to visualize the current state. Because System.Windows.Forms.TreeView supports checkboxes out of the box, the base functionalities like Node.Checked property and TreeView.AfterCheck event are provided by Microsoft.

Node and collection types

Because the behavior of a checkbox and a radio button is not equal, there is an abstract base class which defines the common behaviors and special implementations to meet the type specific behavior. The typed collections hold the associated nodes.

Class Description
TreeNodeBase Base abstract TreeNode used for common features
TreeNodeBaseCollection Collection for TreeNodeBase
TreeNodeCheckBox TreeNode which represents a CheckBox
TreeNodeGroup TreeNode which represents a group node
TreeNodeRadioButton TreeNode which represents a RadioButton
TreeNodeRadioButtonCollection Collection for TreeNodeRadioButton
TreeNodeRadioButtonGroup TreeNode which represents a RadioButton parent node

Because I can’t use the TreeNodeCollection I had to use my own collection types. I’m not happy about the collection design because I had to painfully override every Nodes collection with my own collection type. But I gained the easy use of collection add method which only supports the permitted node types.

For instance, a radio button group can only hold radio buttons, no checkboxes. But a TreeNodeGroup can hold any of the custom node types.

How it works

Every time the user selects a tree node, the AfterCheck event is fired. The TreeViewEventArgs.Node holds the selected node. After casting it to TreeNodeBase type we can call the TreeNodeBase.UpdateCheckState() method. UpdateCheckState() is implemented for each custom node type and does the following:

TreeNodeBaseNot implemented
TreeNodeRadioButtonGroupNot implemented
TreeNodeGroupNot implemented
TreeNodeCheckboxIf the checkbox is checked, the checked image is used, otherwise the unchecked image
TreeNodeRadioButtonIf the radio is checked, the checked image is used, otherwise the unchecked image. The parent (RadioButtonGroup) now cares about the optional update of a last selected radio

Tip to suppress events

Setting the TreeNode.Checked property from within the BeforeCheck or AfterCheck event causes the event to be raised multiple times and can result in unexpected behavior. The TreeViewRadioBox control provides a simple suppress technique to avoid this.

Every time the code switches the state of the checked flag, it has to call:

internal protected void SuspendItemCheckedEvent(bool supressEvent)
     this.suspendItemCheckedEvent_ += (supressEvent)? +1 : -1;

AfterCheck event now only calls code if suspendItemCheckedEvent equals 0. It’s important to use an integer instead of bool value because of nested suppress calls.

Event handling

The event ItemChecked is fired every time a custom node's state has changed. TreeEventArgs.Node holds the selected node. Every node type can have it's own overridden Nodes collection and specific properties.

So we have to cast the node before we can access them.

private void treeViewItemChecked(object sender, 
                       System.Windows.Forms.TreeViewEventArgs e)
   if(e.Node is Raccoom.Windows.Forms.TreeNodeRadioButtonGroup)


Custom drawing

System.Drawing.Graphics class provides a static method which makes it possible to draw on the surface of a bitmap.

The following code draws a checkbox in unchecked state to a bitmap:

Rectangle rect = new Rectangle(0,0,16,16);
Bitmap bitmap = new Bitmap(rect.Width,rect.Height);
using(System.Drawing.Graphics graphics = Graphics.FromImage(bitmap))
    ControlPaint.DrawCheckBox(graphics, rect, 
           ButtonState.Normal | ButtonState.Flat);

After adding this bitmap to the tree view image list, you can fake an unchecked tree node.

The ControlPaint class is not theme aware, so your checkbox will always have the classic Windows style look.

To support themes I used instead of ControlPaint, the excellent code from Don Kackman, A Managed C++ Wrapper Around the Windows XP Theme API to draw my controls theme aware.

Basically the control supports themed and non themed OS.

Using the code

Using this control is common to using System.Windows.Forms.TreeView. You can add nodes to the tree view or his child nodes via the Nodes collection's add method.

This example shows how to add group, checkbox and radio button nodes. This example assumes that you have created an instance of a TreeViewRadioBox control on a Form.

// suspend drawing

We start by adding the first group node.

// create group node <CODEPROJECT> and add it to tree view nodes collection
TreeNodeGroup cpNode = new TreeNodeGroup("Codeproject"); 

Create a radio button group.

// create radio button group node <SURVEY>(holds radio buttons) 
TreeNodeRadioButtonGroup pollNode = 
     new TreeNodeRadioButtonGroup("Survey");
// create first radio button
TreeNodeRadioButton radioNode = new TreeNodeRadioButton 
 ("Desktop applications cannot be replaced by network based applications"); 
// create second radio button 
radioNode = new TreeNodeRadioButton 
 ("There will always be a place for real desktop applications");
// select current node
radioNode.Checked = true;
// create last radio button
group radioNode = new TreeNodeRadioButton 
 ("Desktop applications will all become network based");

Create a new group node and add checkbox and radio buttons.

// create group node for code project settings 
TreeNodeGroup settingNode = new TreeNodeGroup("My settings"); 
// create and add checkbox node <EMAIL Surveys>
settingNode.Nodes.Add(new TreeNodeCheckBox("Email Surveys")); 
settingNode.Nodes.Add(new TreeNodeCheckBox
  ("Use cookies so you don't have to log on again"));
// create group node <NEWSLETTER Topics>
TreeNodeGroup newsletterNode = new TreeNodeGroup("Newsletter Topics");
// add some newsletter topic checkboxes
newsletterNode.Nodes.Add(new TreeNodeCheckBox("Site News"));
newsletterNode.Nodes.Add(new TreeNodeCheckBox("C# articles"));
newsletterNode.Nodes.Add(new TreeNodeCheckBox("All .NET articles"));

Resume painting, finished.

// resume painting

After the compiler was working, it looks like:

Sample screenshot

TreeViewRadioBoxReflection works familiar to the PropertyGrid, it shows the reflected properties (bool and enum) of a type instance. This example assumes that you have created an instance of a TreeViewRadioBoxReflection control on a Form.

treeView.SelectedObject = new System.Windows.Forms.Form();


  • Before you can add child nodes to a node you must add the node to the tree view, otherwise the images are wrong until the user selects the item.

Have phun with it…


Screenshots with different XP themes are available here (animated GIF which opens in new window).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Chris Richner
Software Developer (Senior)
Switzerland Switzerland
My interest is in the future because I am going to spend the rest of my life there. (Charles Kettering)


  • 1996 - 1998 PC Board PPL, HTML, DHTML, Javascript and ASP
  • 1999 - 2001 coding Centura against Sql Database (SqlBase,MSSQL,Oracle)
  • 2002 - 2004 C# Windows Forms
  • 2005 - 2006 C# ASP.NET, Windows Forms
  • 2006 - 2009 C#, WCF, WF, WPF
  • 2010 - 2012 C#, Dynamics CRM, Sharepoint, Silverlight
  • 2013 - 2013 C#, WCF DS (OData), WF, WPF
  • 2014 - 2016 C#, Azure PaaS, Identity, OWIN, OData, Web Api
  • 2017 - now C#, aspnet.core, IdentityServer4, TypeScript & Angular @ Azure IaaS or PaaS


  • family & friends
  • chilaxing ,)
  • coding

You may also be interested in...


Comments and Discussions

GeneralException: Invalid parameter used in System.drawing.dll Pin
brazilectro15-Aug-07 2:49
memberbrazilectro15-Aug-07 2:49 
GeneralRe: Exception: Invalid parameter used in System.drawing.dll Pin
Chris Richner15-Aug-07 7:57
memberChris Richner15-Aug-07 7:57 
GeneralRe: Exception: Invalid parameter used in System.drawing.dll Pin
brazilectro15-Aug-07 13:53
memberbrazilectro15-Aug-07 13:53 
GeneralRe: Exception: Invalid parameter used in System.drawing.dll Pin
Chris Richner25-Sep-07 21:07
memberChris Richner25-Sep-07 21:07 
Generalbug in treeviewradiobox control Pin
naveen.arra9-Aug-07 22:45
membernaveen.arra9-Aug-07 22:45 
GeneralRe: bug in treeviewradiobox control Pin
naveen.arra17-Aug-07 10:53
membernaveen.arra17-Aug-07 10:53 
QuestionException Pin
Dai Bach2-Apr-07 4:43
memberDai Bach2-Apr-07 4:43 
AnswerRe: Exception Pin
Chris Richner8-Apr-07 4:36
memberChris Richner8-Apr-07 4:36 
GeneralRe: Exception Pin
Chris Richner9-Apr-07 14:39
memberChris Richner9-Apr-07 14:39 
GeneralRe: Exception Pin
Dai Bach18-Apr-07 1:52
memberDai Bach18-Apr-07 1:52 
GeneralRe: Exception Pin
Chris Richner19-Apr-07 10:58
memberChris Richner19-Apr-07 10:58 
GeneralRe: Exception Pin
Darren Kelly18-Dec-07 9:26
memberDarren Kelly18-Dec-07 9:26 
GeneralGOOD Pin
Hugo PEREIRA21-Dec-06 3:02
memberHugo PEREIRA21-Dec-06 3:02 
GeneralVarious colors in a treenode text Pin
Saez31-May-06 9:02
memberSaez31-May-06 9:02 
GeneralRe: Various colors in a treenode text Pin
Chris Richner3-Jun-06 15:43
memberChris Richner3-Jun-06 15:43 
Generalhelp !!! Pin
Your details have been updated20-Dec-05 22:03
memberYour details have been updated20-Dec-05 22:03 
GeneralRe: help !!! Pin
Chris Richner21-Dec-05 9:02
memberChris Richner21-Dec-05 9:02 
QuestionAdd richtext to nodes? Pin
Boniolopez13-Aug-05 3:25
memberBoniolopez13-Aug-05 3:25 
GeneralRadio Buttons don't show Pin
Stevan Warwick25-Aug-04 15:43
memberStevan Warwick25-Aug-04 15:43 
GeneralRe: Radio Buttons don't show Pin
marcus.b14-Sep-04 13:09
membermarcus.b14-Sep-04 13:09 
GeneralRe: Radio Buttons don't show Pin
Stevan Warwick20-Sep-04 8:52
memberStevan Warwick20-Sep-04 8:52 
QuestionShould I even try to get this working on Pocket PC 2002? Pin
spamdog20-Aug-04 19:59
memberspamdog20-Aug-04 19:59 
GeneralChanging color of each node Pin
chito17-Aug-04 0:37
memberchito17-Aug-04 0:37 
GeneralRe: Changing color of each node Pin
Chris Richner17-Aug-04 2:32
memberChris Richner17-Aug-04 2:32 
QuestionPocket PC 2002? Pin
spamdog16-Aug-04 16:55
memberspamdog16-Aug-04 16:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.181114.1 | Last Updated 11 Oct 2003
Article Copyright 2003 by Chris Richner
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid