Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / C#
Article

Tri-State TreeView Control

Rate me:
Please Sign up or sign in to vote.
4.42/5 (28 votes)
2 Nov 2005CPL2 min read 396.8K   8.6K   73   91
A TreeView control with tri-state checkboxes.

Introduction

Microsoft provides a TreeView control in the .NET framework, but as usual it doesn't expose all the functionality that the underlying common control provides. It has the possibility to display check-boxes but they can't be tri-state check boxes.

This control adds tri-state check boxes and the necessary handling methods to check/uncheck all sub-items if the user clicks on a node, as well as displays a grey-checked check box for the parent if the siblings have differing check/uncheck states.

Background

A tri-state TreeView is a tree view control that displays check boxes next to the tree nodes. If you click on a check box, it checks (or unchecks) the check box and all sub-nodes.

If the nodes on the same level as the clicked node have differing check states the parent node's check box is grey-checked as well as its parent's and so on.

If you click on a grey-checked check box it unchecks that node and all its subnodes.

How to use the control

Add TriStateTreeView.cs to your project and then simply drop the TriStateTreeView control on a form and use it as a regular TreeView control. The only difference is when you want to access the checked state of a node. Instead of using the treeNode.Checked property you call triStateTreeView.GetChecked(treeNode) resp. triStateTreeView.SetChecked(treeNode, checkState). Instead of a bool these methods take a CheckState.

For example, the following code snippet checks the state of all the top level nodes:

C#
foreach (TreeNode node in m_treeView.Nodes)
{
  if (m_treeView.GetChecked(node) == 
         TriStateTreeView.CheckState.Checked)
    DoFoo(node);
}

How does it work?

The control derives from TreeView and sets the ImageList and SelectedImageList properties for the base control. It overrides the OnClick and OnKeyDown methods.

In the OnKeyDown method, we check if the pressed key is a space, and if it is we change the state of the selected node.

The OnClick method is a little trickier. We have to use the TVM_HITTEST Win32 API message to determine if the user clicked on the icon or on the item. If the user clicked on the icon we change the state of the selected node.

Limitations

This control doesn't support displaying both check boxes and icons. If you need this functionality you have to call additional Win32 API methods. The common control tree view control supports having multiple image lists, but this functionality isn't exposed in .NET.

Remarks

The control makes use of the Skybound.VisualStyle assembly from www.skybound.ca. By commenting out the lines that reference that assembly it will easily work without it. Another way of making the control aware of visual styles is described here.

The demo project consists of an assembly that contains the TriStateTreeView, a demo project and a NUnit test assembly with some tests for the control.

History

  • 26 March 2004 - First version.
  • 28 October 2005 - Added support for visual styles and Before/AfterCheck.

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)


Written By
Software Developer (Senior)
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThis Post is very helpul for me Pin
ashishgupta12125-Mar-13 8:46
ashishgupta12125-Mar-13 8:46 
QuestionGracias Pin
jc2211871-Mar-13 15:08
jc2211871-Mar-13 15:08 
QuestionNot Displaying in Form Pin
akhilrajau14-Dec-12 16:37
akhilrajau14-Dec-12 16:37 
QuestionThank you! Pin
krillgar2-Mar-12 11:32
krillgar2-Mar-12 11:32 
Questionmuy bueno Pin
Member 772271318-Nov-11 10:50
Member 772271318-Nov-11 10:50 
BugRight To Left Pin
nagham_4ng31-Jul-11 23:10
nagham_4ng31-Jul-11 23:10 
GeneralRe: Right To Left Pin
Ebse17-Aug-11 5:20
Ebse17-Aug-11 5:20 
GeneralMy vote of 5 Pin
vstetsko7-Mar-11 9:13
vstetsko7-Mar-11 9:13 
QuestionUnusual Behavior Pin
Phantom2081-Feb-11 6:35
Phantom2081-Feb-11 6:35 
AnswerRe: Unusual Behavior Pin
Phantom2082-Feb-11 5:55
Phantom2082-Feb-11 5:55 
QuestionHow to use this dll in 64 bit mechines Pin
Member 329057315-Sep-10 16:18
Member 329057315-Sep-10 16:18 
AnswerRe: How to use this dll in 64 bit mechines Pin
Cody Tang7-Oct-10 23:30
professionalCody Tang7-Oct-10 23:30 
GeneralRe: How to use this dll in 64 bit mechines Pin
Member 223057026-Dec-10 12:11
Member 223057026-Dec-10 12:11 
GeneralRe: How to use this dll in 64 bit mechines Pin
Cody Tang30-Jul-11 21:49
professionalCody Tang30-Jul-11 21:49 
GeneralRe: How to use this dll in 64 bit mechines Pin
pman30-Jul-11 1:01
pman30-Jul-11 1:01 
GeneralImage problem Pin
Devon Peterson17-Feb-10 12:53
Devon Peterson17-Feb-10 12:53 
GeneralRe: Image problem Pin
Devon Peterson17-Feb-10 13:20
Devon Peterson17-Feb-10 13:20 
GeneralAdded ability to have disabled nodes. You might find this usefull. [modified] Pin
David Catriel17-Jun-09 2:49
David Catriel17-Jun-09 2:49 
As noted in a previous message, I found this control extremely useful, so thx a bunch for that.

One thing I was missing, however, was the ability to enable and disable specific tree nodes. Adding an Enabled property to a derived class of the TreeNode would have been too complex because I'd have to inherit from several other classes as well and it would get messy.

Instead, I added a DisabledColor property to your TriStateTreeView. Set this property to a particular color (such as SystemColors.GrayText), and then whenever you need to disable a node, set its ForeColor to this color as well. The TriStateTreeView will then properly manage the click states of all parent and child nodes accordingly.

I can't find a way to put an attachment here, so I'm forced to paste the class.

Hope it comes in handy to someone.

[Note: the CodeProject is truncating the pasted code, as I've probably hit a maximum length or something. See my response to this note with the rest of the code.]

// ---------------------------------------------------------------------------------------------<br />
#region // Copyright (c) 2004-2005, SIL International. All Rights Reserved.   <br />
// <copyright from='2004' to='2005' company='SIL International'><br />
//		Copyright (c) 2004-2005, SIL International. All Rights Reserved.   <br />
//    <br />
//		Distributable under the terms of either the Common Public License or the<br />
//		GNU Lesser General Public License, as specified in the LICENSING.txt file.<br />
// </copyright> <br />
#endregion<br />
// <br />
// File: TriStateTreeView.cs<br />
// Responsibility: Eberhard Beilharz/Tim Steenwyk<br />
// <br />
// <remarks><br />
// Downloaded from the CodeProject, at http://www.codeproject.com/KB/tree/TriStateTreeViewSubmissio.aspx?msg=3054765#xx3054765xx<br />
// </remarks><br />
// ---------------------------------------------------------------------------------------------<br />
using System;<br />
using System.Collections;<br />
using System.ComponentModel;<br />
using System.Drawing;<br />
using System.Data;<br />
using System.Runtime.InteropServices;<br />
using System.Windows.Forms;<br />
using System.Runtime.Serialization;<br />
<br />
namespace WinControls<br />
{<br />
	/// ----------------------------------------------------------------------------------------<br />
	/// <summary><br />
	/// A tree view with tri-state check boxes<br />
	/// </summary><br />
	/// <remarks><br />
	/// REVIEW: If we want to have icons in addition to the check boxes, we probably have to <br />
	/// set the icons for the check boxes in a different way. The windows tree view control<br />
	/// can have a separate image list for states.<br />
	/// </remarks><br />
	/// ----------------------------------------------------------------------------------------<br />
	public class TriStateTreeView : TreeView<br />
	{<br />
      private System.Drawing.Color mDisabledNodeColor;<br />
<br />
      /// <summary><br />
      /// Gets/sets the color of the disabled nodes. Used to tell if a node should be checked off or not.<br />
      /// </summary><br />
      public System.Drawing.Color DisabledNodeColor<br />
      {<br />
         get { return mDisabledNodeColor; }<br />
         set { mDisabledNodeColor = value; }<br />
      }<br />
	<br />
		private System.Windows.Forms.ImageList m_TriStateImages;<br />
		private System.ComponentModel.IContainer components;<br />
		/// <summary><br />
		/// The check state<br />
		/// </summary><br />
		/// <remarks>The states corresponds to image index</remarks><br />
		public enum CheckState<br />
		{<br />
			/// <summary>greyed out</summary><br />
			GreyChecked = 0,<br />
			/// <summary>Unchecked</summary><br />
			Unchecked = 1,<br />
			/// <summary>Checked</summary><br />
			Checked = 2,<br />
		}<br />
<br />
		#region Redefined Win-API structs and methods<br />
		/// <summary></summary><br />
		[StructLayout(LayoutKind.Sequential, Pack=1)]<br />
			public struct TV_HITTESTINFO<br />
		{<br />
			/// <summary>Client coordinates of the point to test.</summary><br />
			public Point pt;<br />
			/// <summary>Variable that receives information about the results of a hit test.</summary><br />
			public TVHit flags;<br />
			/// <summary>Handle to the item that occupies the point.</summary><br />
			public IntPtr hItem;<br />
		}<br />
<br />
		/// <summary>Hit tests for tree view</summary><br />
		[Flags]<br />
		public enum TVHit<br />
		{<br />
			/// <summary>In the client area, but below the last item.</summary><br />
			NoWhere = 0x0001,<br />
			/// <summary>On the bitmap associated with an item.</summary><br />
			OnItemIcon = 0x0002,<br />
			/// <summary>On the label (string) associated with an item.</summary><br />
			OnItemLabel = 0x0004,<br />
			/// <summary>In the indentation associated with an item.</summary><br />
			OnItemIndent = 0x0008,<br />
			/// <summary>On the button associated with an item.</summary><br />
			OnItemButton = 0x0010,<br />
			/// <summary>In the area to the right of an item. </summary><br />
			OnItemRight = 0x0020,<br />
			/// <summary>On the state icon for a tree-view item that is in a user-defined state.</summary><br />
			OnItemStateIcon = 0x0040,<br />
			/// <summary>On the bitmap or label associated with an item. </summary><br />
			OnItem = (OnItemIcon | OnItemLabel | OnItemStateIcon),<br />
			/// <summary>Above the client area. </summary><br />
			Above = 0x0100,<br />
			/// <summary>Below the client area.</summary><br />
			Below = 0x0200,<br />
			/// <summary>To the right of the client area.</summary><br />
			ToRight = 0x0400,<br />
			/// <summary>To the left of the client area.</summary><br />
			ToLeft = 0x0800<br />
		}<br />
<br />
		/// <summary></summary><br />
		public enum TreeViewMessages<br />
		{<br />
			/// <summary></summary><br />
			TV_FIRST            = 0x1100,      // TreeView messages<br />
			/// <summary></summary><br />
			TVM_HITTEST         = (TV_FIRST + 17),<br />
		}<br />
<br />
		/// <summary></summary><br />
		[DllImport("user32.dll", CharSet=CharSet.Auto)]<br />
		public static extern int SendMessage(IntPtr hWnd, TreeViewMessages msg, int wParam, ref TV_HITTESTINFO lParam);<br />
		#endregion<br />
<br />
		#region Constructor and destructor<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Initializes a new instance of the <see cref="TriStateTreeView"/> class.<br />
		/// </summary><br />
		/// ------------------------------------------------------------------------------------<br />
		public TriStateTreeView()<br />
		{<br />
			// This call is required by the Windows.Forms Form Designer.<br />
			InitializeComponent();<br />
         mDisabledNodeColor = SystemColors.GrayText;<br />
			ImageList = m_TriStateImages;<br />
			ImageIndex = (int)CheckState.Unchecked;<br />
			SelectedImageIndex = (int)CheckState.Unchecked;<br />
		}<br />
<br />
		/// -----------------------------------------------------------------------------------<br />
		/// <summary> <br />
		/// Clean up any resources being used.<br />
		/// </summary><br />
		/// <param name="disposing"><c>true</c> to release both managed and unmanaged <br />
		/// resources; <c>false</c> to release only unmanaged resources. <br />
		/// </param><br />
		/// -----------------------------------------------------------------------------------<br />
		protected override void Dispose( bool disposing )<br />
		{<br />
			if( disposing )<br />
			{<br />
				if(components != null)<br />
				{<br />
					components.Dispose();<br />
				}<br />
			}<br />
			base.Dispose( disposing );<br />
		}<br />
		#endregion<br />
<br />
		#region Component Designer generated code<br />
		/// -----------------------------------------------------------------------------------<br />
		/// <summary> <br />
		/// Required method for Designer support - do not modify <br />
		/// the contents of this method with the code editor.<br />
		/// </summary><br />
		/// -----------------------------------------------------------------------------------<br />
		private void InitializeComponent()<br />
		{<br />
			this.components = new System.ComponentModel.Container();<br />
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(TriStateTreeView));<br />
			this.m_TriStateImages = new System.Windows.Forms.ImageList(this.components);<br />
			// <br />
			// m_TriStateImages<br />
			// <br />
			this.m_TriStateImages.ImageSize = new System.Drawing.Size(16, 16);<br />
			this.m_TriStateImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("m_TriStateImages.ImageStream")));<br />
			this.m_TriStateImages.TransparentColor = System.Drawing.Color.Magenta;<br />
<br />
		}<br />
		#endregion<br />
<br />
		#region Hide no longer appropriate properties from Designer<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// <br />
		/// </summary><br />
		/// ------------------------------------------------------------------------------------<br />
		[Browsable(false)]<br />
		public new bool CheckBoxes<br />
		{<br />
			get { return base.CheckBoxes; }<br />
			set { base.CheckBoxes = value; }<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// <br />
		/// </summary><br />
		/// ------------------------------------------------------------------------------------<br />
		[Browsable(false)]<br />
		public new int ImageIndex<br />
		{<br />
			get { return base.ImageIndex; }<br />
			set { base.ImageIndex = value; }<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// <br />
		/// </summary><br />
		/// ------------------------------------------------------------------------------------<br />
		[Browsable(false)]<br />
		public new ImageList ImageList<br />
		{<br />
			get { return base.ImageList; }<br />
			set { base.ImageList = value; }<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// <br />
		/// </summary><br />
		/// ------------------------------------------------------------------------------------<br />
		[Browsable(false)]<br />
		public new int SelectedImageIndex<br />
		{<br />
			get { return base.SelectedImageIndex; }<br />
			set { base.SelectedImageIndex = value; }<br />
		}<br />
		#endregion<br />
<br />
		#region Overrides<br />
      /*protected new TriStateTreeNode[] Nodes <br />
      { <br />
         this.nodes<br />
      }*/<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Called when the user clicks on an item<br />
		/// </summary><br />
		/// <param name="e"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		protected override void OnClick(EventArgs e)<br />
		{<br />
			base.OnClick (e);<br />
<br />
			TV_HITTESTINFO hitTestInfo = new TV_HITTESTINFO();<br />
			hitTestInfo.pt = PointToClient(Control.MousePosition);<br />
<br />
			SendMessage(Handle, TreeViewMessages.TVM_HITTEST,<br />
				0, ref hitTestInfo);<br />
			if ((hitTestInfo.flags & TVHit.OnItemIcon) == TVHit.OnItemIcon)<br />
			{<br />
				TreeNode node = GetNodeAt(hitTestInfo.pt);<br />
            if (node != null)<br />
            {<br />
               ChangeNodeState(node);<br />
            }<br />
			}<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Toggle item if user presses space bar<br />
		/// </summary><br />
		/// <param name="e"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		protected override void OnKeyDown(KeyEventArgs e)<br />
		{<br />
			base.OnKeyDown (e);<br />
<br />
			if (e.KeyCode == Keys.Space)<br />
				ChangeNodeState(SelectedNode);<br />
		}<br />
		#endregion<br />
<br />
		#region Private methods<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Checks or unchecks all children<br />
		/// </summary><br />
		/// <param name="node"></param><br />
		/// <param name="state"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		private void CheckNode(TreeNode node, CheckState state)<br />
		{<br />
			bool checkSet = InternalSetChecked(node, state);<br />
<br />
         if (checkSet)<br />
         {<br />
            foreach (TreeNode child in node.Nodes)<br />
            {<br />
               CheckNode(child, state);<br />
            }<br />
         }<br />
<br />
         ChangeParent(node.Parent);<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Called after a node changed its state. Has to go through all direct children and<br />
		/// set state based on children's state.<br />
		/// </summary><br />
		/// <param name="node">Parent node</param><br />
		/// ------------------------------------------------------------------------------------<br />
		private void ChangeParent(TreeNode node)<br />
		{<br />
         if (node == null)<br />
         {<br />
            return;<br />
         }<br />
<br />
			CheckState state = GetChecked(node.FirstNode);<br />
			foreach (TreeNode child in node.Nodes)<br />
				state &= GetChecked(child);<br />
<br />
         if (InternalSetChecked(node, state))<br />
         {<br />
            ChangeParent(node.Parent);<br />
         }<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Handles changing the state of a node<br />
		/// </summary><br />
		/// <param name="node"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		protected void ChangeNodeState(TreeNode node)<br />
		{<br />
         if (node.ForeColor != mDisabledNodeColor)<br />
         {<br />
            BeginUpdate();<br />
            CheckState newState;<br />
            if (node.ImageIndex == (int)CheckState.Unchecked || node.ImageIndex < 0)<br />
            {<br />
               newState = CheckState.Checked;<br />
            }<br />
            else<br />
            {<br />
               newState = CheckState.Unchecked;<br />
            }<br />
            CheckNode(node, newState);<br />
            ChangeParent(node.Parent);<br />
            EndUpdate();<br />
         }<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Sets the checked state of a node, but doesn't deal with children or parents<br />
		/// </summary><br />
		/// <param name="node">Node</param><br />
		/// <param name="state">The new checked state</param><br />
		/// <returns><c>true</c> if checked state was set to the requested state, otherwise<br />
		/// <c>false</c>.</returns><br />
		/// ------------------------------------------------------------------------------------<br />
		private bool InternalSetChecked(TreeNode node, CheckState state)<br />
		{<br />
         bool returnValue = true;<br />
         if (node.ForeColor != mDisabledNodeColor)<br />
         {<br />
            TreeViewCancelEventArgs args = new TreeViewCancelEventArgs(node, false, TreeViewAction.Unknown);<br />
            OnBeforeCheck(args);<br />
            if (args.Cancel)<br />
            {<br />
               returnValue = false;<br />
            }<br />
<br />
            node.ImageIndex = (int)state;<br />
            node.SelectedImageIndex = (int)state;<br />
<br />
            OnAfterCheck(new TreeViewEventArgs(node, TreeViewAction.Unknown));<br />
         }<br />
         else<br />
         {<br />
            returnValue = false;<br />
         }<br />
         return returnValue;<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Build a list of all of the tag data for checked items in the tree.<br />
		/// </summary><br />
		/// <param name="node"></param><br />
		/// <param name="list"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		private void BuildTagDataList(TreeNode node, ArrayList list)<br />
		{<br />
			if (GetChecked(node) == CheckState.Checked && node.Tag != null)<br />
				list.Add(node.Tag);<br />
<br />
			foreach (TreeNode child in node.Nodes)<br />
				BuildTagDataList(child, list);<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Look through the tree nodes to find the node that has given tag data and check it.<br />
		/// </summary><br />
		/// <param name="node"></param><br />
		/// <param name="tag"></param><br />
		/// <param name="state"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		private void FindAndCheckNode(TreeNode node, object tag, CheckState state)<br />
		{<br />
			if (node.Tag != null && node.Tag.Equals(tag))<br />
			{<br />
				SetChecked(node, state);<br />
				return;<br />
			}<br />
<br />
			foreach (TreeNode child in node.Nodes)<br />
				FindAndCheckNode(child, tag, state);<br />
		}<br />
		#endregion<br />
<br />
		#region Public methods<br />
      /// ------------------------------------------------------------------------------------<br />
      /// <summary><br />
      /// Gets the checked state of a node<br />
      /// </summary><br />
      /// <param name="nodeName">Node name</param><br />
      /// <returns>The checked state</returns><br />
      /// ------------------------------------------------------------------------------------<br />
      public CheckState GetChecked(string nodeName)<br />
      {<br />
         CheckState returnCheckState = CheckState.GreyChecked;<br />
<br />
         TreeNode[] nodes = this.Nodes.Find(nodeName, true);<br />
         if (nodes != null && nodes.Length > 0)<br />
         {<br />
            returnCheckState = GetChecked(nodes[0]);<br />
         }<br />
         else<br />
         {<br />
            throw new Exception("Node " + nodeName + " not found.");<br />
         }<br />
         return returnCheckState;<br />
      }<br />
<br />
      /// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Gets the checked state of a node<br />
		/// </summary><br />
		/// <param name="node">Node</param><br />
		/// <returns>The checked state</returns><br />
		/// ------------------------------------------------------------------------------------<br />
		public CheckState GetChecked(TreeNode node)<br />
		{<br />
			if (node.ImageIndex < 0)<br />
				return CheckState.Unchecked;<br />
			else<br />
				return (CheckState)node.ImageIndex;<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Sets the checked state of a node<br />
		/// </summary><br />
		/// <param name="node">Node</param><br />
		/// <param name="state">The new checked state</param><br />
		/// ------------------------------------------------------------------------------------<br />
		public void SetChecked(TreeNode node, CheckState state)<br />
		{<br />
         bool stateChanged = InternalSetChecked(node, state);<br />
<br />
         if (stateChanged)<br />
         {<br />
            CheckNode(node, state);<br />
         }<br />
			ChangeParent(node.Parent);<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Find a node in the tree that matches the given tag data and set its checked state<br />
		/// </summary><br />
		/// <param name="tag"></param><br />
		/// <param name="state"></param><br />
		/// ------------------------------------------------------------------------------------<br />
		public void CheckNodeByTag(object tag, CheckState state)<br />
		{<br />
			if (tag == null)<br />
				return;<br />
			foreach (TreeNode node in Nodes)<br />
				FindAndCheckNode(node, tag, state);<br />
		}<br />
<br />
		/// ------------------------------------------------------------------------------------<br />
		/// <summary><br />
		/// Return a list of the tag data for all of the checked items in the tree<br />
		/// </summary><br />
		/// <returns></returns><br />
		/// ------------------------------------------------------------------------------------<br />
		public ArrayList GetCheckedTagData()<br />
		{<br />
			ArrayList list = new ArrayList();<br />
<br />
			foreach (TreeNode node in Nodes)<br />
				BuildTagDataList(node, list);<br />
			return list;<br />
		}<br />
		#endregion<br />
	}<br />
}<br />



modified on Tuesday, October 13, 2009 12:07 PM

GeneralRe: Added ability to have disabled nodes. You might find this usefull. Pin
giova12-Oct-09 22:53
giova12-Oct-09 22:53 
GeneralRe: Added ability to have disabled nodes. You might find this usefull. Pin
David Catriel13-Oct-09 5:07
David Catriel13-Oct-09 5:07 
GeneralRe: Added ability to have disabled nodes. You might find this usefull. Pin
David Catriel13-Oct-09 6:07
David Catriel13-Oct-09 6:07 
GeneralAbsolutely awesome Pin
David Catriel26-May-09 3:48
David Catriel26-May-09 3:48 
Generalcontains node! Pin
njuniorba7-May-09 15:07
njuniorba7-May-09 15:07 
GeneralDisable Node Pin
kjward20-Apr-09 4:53
kjward20-Apr-09 4:53 
GeneralRe: Disable Node Pin
David Catriel10-Jun-09 8:59
David Catriel10-Jun-09 8:59 

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.