Click here to Skip to main content
6,292,426 members and growing! (12,003 online)
Email Password   helpLost your password?
Desktop Development » Tree Controls » TreeView Controls     Intermediate License: The Code Project Open License (CPOL)

DataBound TreeView

By Jorge Bay Gondra

A TreeView that can be bound to a DataTable, and can keep track of changes in it.
C#, Windows, .NET, Visual Studio, ADO.NET, Dev
Posted:11 Oct 2005
Updated:25 Oct 2006
Views:43,033
Bookmarked:53 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
19 votes for this article.
Popularity: 5.40 Rating: 4.22 out of 5
2 votes, 10.5%
1

2
1 vote, 5.3%
3
4 votes, 21.1%
4
12 votes, 63.2%
5

Changes made to the table in the Datagrid are shown at the same time at the Treeview (from demo project).

Changes made to the table in the DataGrid are shown at the same time at the TreeView (from demo project).

Introduction

Like so many others, when I needed to use the TreeView control, I found myself doing a Load method adapting the data from a DataTable or a DataView into the TreeView, over and over again. Furthermore, I had to maintain the same data in the control if the values changed.

The purpose of this article is to show you how to develop a TreeView that can be bound to a datasource and can keep track of the changes made in the data, updating the nodes.

Main Objective

  • Load the data in the tree structure.
  • Keep track of changes in the data, showing them in the control.
  • Expose a get/set property like SelectedValue besides SelectedNode, generally you have the value of the node you want to select (but not the node itself!!!).

Class Structure

There are two classes in the project, the TreeNodeBound class that inherits from TreeNode and exposes two properties: Value and ParentValue; and the TreeViewBound (the control itself) class that exposes the DataSource, DisplayMember, ValueMember, and ParentMember properties.

Loading the Data

Let's have a look at the LoadTree function in the TreeViewBound class. I used a Hashtable to place the nodes by ValueMember, that's where the trick is.

private void LoadTree()
{
    
    if (this._datasource != null)
    {
        Clear();
        //Iterate throght the DataRow Collection

        foreach (DataRow dr in this._datasource.Rows)
        {
            TreeNodeBound node = 
                new TreeNodeBound(dr[this._displayMember].ToString());
            node.Value = dr[this._valueMember];
            node.ParentValue = dr[this._parentMember];
            //Add it to the HashTable

            _nodesByValueMember.Add(node.Value, node);
        }
        //Iterate throught the nodes Collection

        foreach (TreeNodeBound node in _nodesByValueMember.Values)
        {
            if (node.ParentValue != _rootParentValue)
            {
                //look for the parent node

                TreeNodeBound parent = 
                    (TreeNodeBound) _nodesByValueMember[node.ParentValue];
                //add it to the nodes collection of the parent node

                parent.Nodes.Add(node);
            }
            else
            {
                //the node is a Root, add it to the root collection

                base.Nodes.Add(node);
            }
        }
    }
}

First, I create the nodes and add it to the Hashtable. Then, I iterate through the nodes, look for the parent node of the node (by the ValueMember again) and add it as a child of the parent. If the node has no parent, it's a root node and I have to add it to the root collection.

Because classes in .NET are reference types, the whole tree structure is loaded. By doing this, we avoid doing a while (!finish) type algorithm, very frequently used in biz.

Keeping Track of Data Changes

For that, I subscribe to the events in the DataSource property.

//subscribe to datatable events

value.RowDeleting += new DataRowChangeEventHandler(value_RowDeleting);
value.RowChanged += new DataRowChangeEventHandler(value_RowChanged);

There are four possible changes that are taken care of:

  • Adding
  • Deleting
  • Modifying the DisplayMember value of a node.
  • Modifying the parent value (which involves removing it from the old parent collection and adding it to the new one).

Getting/Setting the SelectedValue

Both cases are trouble-free because of the use of the TreeNodeBound class and the Hashtable.

public object SelectedValue
{
    get
    {
        if (this.SelectedNode != null)
        {
            return ((TreeNodeBound)this.SelectedNode).Value;
        }
        else
        {
            return null;
        }
    }
    set
    {
        if (value != null)
        {
            this.SelectedNode = 
                (TreeNodeBound) _nodesByValueMember[value];
        }
    }
}

Summary

At first, I came with the idea of a TreeView control that could be bound to any object that implements IList or IListSource like in other controls such as the ComboBox, but with this type of data sources the control couldn't keep track of changes. So, I cut back some functionality to add another one, which I think, is more useful. I look forward to your thoughts.

History

  • October 11th, 2005 - article submitted.

License

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

About the Author

Jorge Bay Gondra


Member
Jorge has been working with Microsoft technologies for more than 10 years. Born in Argentina, he lives in Spain since 2004.
He worked as a consultant for mayor companies including Log, HP and Avanade and holds some technical certifications including MCSD and MCAD.

Currently, He is developing the ASP.NET MVC open source project prsync.com.

Follow him on Twitter: twitter.com/jorgebg

Occupation: Software Developer
Location: Spain Spain

Other popular Tree Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 8 of 8 (Total in Forum: 8) (Refresh)FirstPrevNext
General5 PinmemberJosemaproject6:04 25 Feb '09  
GeneralNice App PinmemberFranciscoR3:54 31 Jan '07  
GeneralDataViewManager Pinmemberiakob3:56 11 Jan '07  
GeneralYou must ignore or exclude items where ID = ParentID PinmemberDMILE52511:29 25 Oct '06  
GeneralTreeview with database Pinmemberkenneth23718:29 23 Oct '06  
GeneralRe: Treeview with database PinmemberJorge Bay Gondra23:38 24 Oct '06  
NewsNew site PinmemberJorge Bay Gondra4:56 23 Aug '06  
GeneralRe: New site [modified] Pinmemberjosemaocu5:00 23 Aug '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 25 Oct 2006
Editor: Smitha Vijayan
Copyright 2005 by Jorge Bay Gondra
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project