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

How to handle custom node state images in a TreeView (e.g. tristate checkboxes)

Rate me:
Please Sign up or sign in to vote.
3.79/5 (9 votes)
4 Jun 2006CPOL2 min read 76.9K   1.7K   30   2
Use custom state images for your nodes within minutes.

Sample Image - customstatetreeview.jpg

Introduction

Caused by the new features of .NET 2.0 and VS 2005 I started to write the Enhanced BrowseForFolder styled TreeView (TreeViewStrategy) code from the ground up new. As I came along the new TreeView features, I figured out that it's now possible to use state images in an easy way. So my first take was to implement tristate checkboxes, a useful feature in a folder browser. I realized that, with a few lines of code, state images can be used in many scenarios, that's the reason why you're reading these lines. Hope it's useful for your development as well.

Design

Image 2

CustomStateTreeView inherits from System.Windows.Forms.TreeView and expects its nodes to implement the IStateTreeNode interface. The following events/methods are overridden to provide the custom state check logic:

  • OnHandleCreated - Used to create the StateImageList.
  • OnKeyDown - Hit testing.
  • OnMouseDown - Hit testing.

To override, these methods became necessary because:

  • out of the box, the control only handles node states if CheckBoxes are enabled.
  • the boolean check flag of a System.Windows.Forms.TreeNode just knows two states.

To implement the desired behaviour, I wrote custom code to handle the node state. The tree view now delegates the state change to the node. The node itself is responsible to change its state accurate to its current context and data.

KeyDown and MouseDown now determine the hit test result to check if the user changed the check state of a certain node. If this happens, the custom Check method is called.

C#
System.Windows.Forms.TreeViewHitTestInfo info = 
                             this.HitTest(e.X, e.Y);
if (info.Node != null && info.Location.ToString() == "StateImage")
{
     OnCustomCheck((TriStateTreeNode)info.Node, 
            System.Windows.Forms.TreeViewAction.ByMouse);
}

The OnCustomCheck method preserves the BeforeCheck and AfterCheck event logic. So it's still possible to cancel a Check action.

C#
protected virtual void OnCustomCheck(System.Windows.Forms.TreeNode node, 
                  System.Windows.Forms.TreeViewAction action)
{
      System.Windows.Forms.TreeViewCancelEventArgs e = new 
         System.Windows.Forms.TreeViewCancelEventArgs(node, false, action);
      OnBeforeCheck(e);
      if (e.Cancel) return;
      //
      if (node is IStateTreeNode)
      {
         ((IStateTreeNode)node).UpdateState(e);
      }
      //
      OnAfterCheck(new System.Windows.Forms.TreeViewEventArgs(node, action));
}

E.g.: for the tri-state tree node, I used the following interface implementation:

C#
public virtual System.Windows.Forms.CheckState CheckState
{
   get
   {
      return _checkState;
    }
    set
    {
       _checkState = value;
       //
       StateImageIndex = (int)value;
    }
}

void IStateTreeNode.UpdateState(System.Windows.Forms.TreeViewCancelEventArgs e)
{
    switch (CheckState)
    {
        case System.Windows.Forms.CheckState.Checked:
            this.CheckState = System.Windows.Forms.CheckState.Indeterminate;
            break;
        case System.Windows.Forms.CheckState.Indeterminate:
            CheckState = System.Windows.Forms.CheckState.Unchecked;
            break;
        case System.Windows.Forms.CheckState.Unchecked:
            CheckState = System.Windows.Forms.CheckState.Checked;
            break;
    }
}

Usage

To use state images in your project, add CustomStateTreeView.cs and derive your tree view from CustomStateTreeView. Override CreateStateImages() to fill your state images into the StateImageList. On the other side, implement IStateTreeNode to your TreeNode classes, and switch StateImageIndex there to show the image you added to visualize the desired state.

Conclusion

Tri-state nodes are nice, but bear in mind that features like load on demand and complex recursive node checking aren't part of this article. This one just lets you use custom state images with a few lines of code.

Enjoy!

License

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


Written By
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)

Biography

  • 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

Interests

  • family & friends
  • chilaxing ,)
  • coding

Comments and Discussions

 
GeneralBypassing NET StateImageList size restriction Pin
OrlandoCurioso6-Jun-06 2:01
OrlandoCurioso6-Jun-06 2:01 
GeneralRe: Bypassing NET StateImageList size restriction Pin
Chris Richner6-Jun-06 2:51
Chris Richner6-Jun-06 2:51 
Hi OrlandoCurioso,

Thanks for sharing this knowledge.

myMsg.BehindDaKeys = "Chris Richner";

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.