Click here to Skip to main content
15,879,535 members
Articles / Web Development / ASP.NET
Article

Creating a highly manageable TreeView control using Microsoft Web TreeView control

Rate me:
Please Sign up or sign in to vote.
4.46/5 (15 votes)
20 Sep 2005CPOL4 min read 144K   3.7K   62   24
An atricle on how to implement a manageable treeview architecture.

Image 1

Introduction

We all know the power of Microsoft Management Console (MMC). MMC is Microsoft’s standard platform for administrative and system management tools. MMC lets you use snap-ins to manage every part of Windows and even other applications from the same standard interface. The purpose of this article is to provide a MMC like interface over the web (I call it MMC Web). MMC Web represents a common view point to a variety of administrative tasks, which will make life more easy. MMC Web is made on an easy attachable framework that will let users to add / remove modules as well as reuse them over time with less hassle.

Requirements

The code has been written using Microsoft Web TreeView control, therefore the scripts to be run to render the tree should be in their proper place. The scripts are provided in the download, under the tools folder. To make sure that the tree view works properly, all you need to do is to copy the webctrl_client folder to your IIS wwwroot directory.

Using the code

Now, assume that we want to represent a simple organizational hierarchy. To dig a little deeper, assume that there is a company, under it there are some departments, and every department is composed of some sections. In a more technical fashion, there are three entities Company, Department and Section, where departments are children of the company and sections are children of a department. Now, to achieve this form of structure in a tree, the simplest steps are:

  1. Implementing the IProvider interface: create object specific provider classes (e.g. CompanyProvider). These classes will be responsible for fetching data from the data source for a specific ID. The ID will be provided internally by the framework according to the hierarchy defined in the XML schema.
  2. Implementing the IRenderer interface: create object specific renderer classes (e.g. CompanyRenderer). These classes will provide the rendering option for the tree, like how the tree will be rendered.
  3. Construct an XML that will define the relationships among the objects and their behaviour type.

    The XML format is as shown below:

    XML
    <company assembly="TreeView.Objects" 
             provider="TreeView.Objects.Provider.CompanyProvider" 
             renderer="TreeView.Objects.Renderer.CompanyRenderer" 
             expanded = "true" >
        <department assembly="TreeView.Objects" 
               provider="TreeView.Objects.Provider.DepartmentProvider" 
               renderer="TreeView.Objects.Renderer.DepartmentRenderer" 
               expanded = "true" >
           <section assembly="TreeView.Objects" 
                provider="TreeView.Objects.Provider.SectionProvider" 
                renderer="TreeView.Objects.Renderer.SectionRenderer" 
                expanded = "false"/>
        </department>
    </company >

    Each XML node contains a few attributes which are:

    1. assembly
      • defines where the renderers, providers and objects could be found.
    2. provider
      • defines the object type of the provider class.
    3. renderer
      • defines the object type of the renderer class.
    4. expanded
      • defines the status of the tree node.

    All these attributes are used to build the object model dynamically from the XML.

  4. Finally, we need to drag the ExtendedTreeView control (the wonder control) to a web page and call the LoadXml function with the proper server path at page load.

Once the loading is complete we then need the proper entity ID at each selection change, using which we will load the entity information at the right side of the tree. During construction, each tree node ID is internally constructed by an '_' separated ID and an object name format by the treeview framework, which does solve our problem. At selection, we just need to manage to get the proper tree node object from the '.' separated string node ID.

C#
private void treeView_SelectedIndexChange(object sender, 
            Microsoft.Web.UI.WebControls.TreeViewSelectEventArgs e)
{
    // gets the node id in dot separated format.
    _NodeID = e.NewNode;
    // load
    LoadPage( _NodeID );
}

Now, to show the entity detail, we can create controls for entity names (example: company.ascx). To make the loading of different entities possible in the most uniform way, each control needs to extend a BaseControl class and implement an IHost interface. The interface will make the control pluggable to the treeview framework, as on each selection change from the first part of the node ID, we load the control and load the entity information using the second part of the node string with the help of the IHost interface.

C#
private void LoadPage( string nodeID  )
{
    BaseControl control = null;
    // this line does all tricks of geting  real from dot separated node ID
    TreeNode node = treeView.GetNodeFromIndex( nodeID );
    // make the id
    string[] nodeParts =  node.ID.Split( '_' );
    //save the ids
    _PropertyID = Int32.Parse(  nodeParts[ 1 ] );
    _ControlID = nodeParts[ 0 ];

    control = ( BaseControl ) pnlRenderer.FindControl( _ControlID );

    if( control == null )
    {
        // get the control name
        string controlName = "Controls/" + nodeParts [ 0 ] + ".ascx";
        //Control control =  LoadControl( controlName );
        control = ( BaseControl ) LoadControl( controlName );
        control.ID = _ControlID; 

        if ( control != null )
        {
            pnlRenderer.Controls.Clear();
            pnlRenderer.Controls.Add( control );
            // bind the events
            control.PreRender +=new EventHandler(control_PreRender);
            control.OnChange+=new OnChangeEvent(control_OnChange);
        }
    }//if( control == null )

    IHost loader = ( IHost ) control; 
    // load the module
    if ( nodeID != String.Empty )
    {
        loader.LoadTab( _PropertyID );
    }
}

About the framework

As far as we have seen, the treeview uses a simple XML file to build its object model. Now, let's look in a little deeper and see how the job is really done. The treeview framework uses a control named extendedTreeView that has been built on the Microsoft Web TreeView control. It extends all the functionalities of the existing TreeView control. In addition it gives a function that is the heart of building a tree in the most friendly fashion.

C#
public void LoadTree( string ServerPath );

As you can see, the function expects a server path for the XML file that contains the definition of the tree structure. Once the path is provided, it loads an object model recursively from the XML.

Part of the source follows:

C#
private Defination FillObject( XmlNode rootNode )
{
    Assembly ass =  Assembly.Load(  rootNode.Attributes["assembly"].Value );

    Defination def = new Defination();
    // create the provider object
    object providerObject = 
      Activator.CreateInstance( ass.GetType( 
      rootNode.Attributes["provider"].Value, true ) );
    def.Provider = ( Interface.IProvider ) providerObject;
    // create the renderer object
    object rendererObject = 
      Activator.CreateInstance( ass.GetType( 
      rootNode.Attributes["renderer"].Value, true ) );
    def.Renderer = ( Interface.IRenderer ) rendererObject;
    // will the node be expanded
    def.IsExpanded = bool.Parse( rootNode.Attributes["expanded"].Value );
    return def; 
}

After it is done constructing the object from the XML file, it then uses the model to build up a tree structure. The process is to start constructing the tree from the root node and then go down from the highest level until the leaf is encountered.

C#
public void LoadTree( string serverPath )
{
    Schema schema = new Schema( serverPath );
    Defination defination = schema.RootNode;
    ExecuteDef( defination, 0 , null );
}
private void ExecuteDef( Defination defination, 
                         int parentID, TreeNode parentNode  )
{
    IProvider provider = defination.Provider;
    IList list =  provider.GetAll( parentID );
    LoadList( list, defination, parentID, parentNode );
}

private void LoadList( IList list, Defination def, 
                       int parentNodeID, TreeNode parentNode  )
{
    foreach( object obj in list )
    {
        IRenderer renderer = def.Renderer;
        renderer.Set( obj );
        TreeNode node = ConstructNode( renderer, parentNodeID );
        PopulateNode( node, parentNodeID, parentNode );
        if( def.IsExpanded )
        {
            LoadNode( renderer, def, node );
        }
    }// end foreach
}

Finally

MMC Web will help users to reduce the number of lines of code by reusing the most common set of modules (Ex. password change, add new registration, and many more) which are already written by someone else. Thus it will help ISVs grow better.

License

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


Written By
Software Developer Telerik Corporation
Bangladesh Bangladesh
Passionate about cutting edge technologies and a .net enthusiast. I have played roles in variety of products starting from University automation to web 2.0 start-page (www.pageflakes.com).

Currently, working at Telerik Inc (www.telerik.com), the premium rad control provider for asp.net and winforms. I am a active contributor and member at www.dotnetslackers.com. In addition, i do a frequent post on my blog about LINQ, C#, Asp.net and about my projects.

I am Microsoft MVP. I love to travel and meet cool people.

Comments and Discussions

 
QuestionTreeView.Objects.dll and TreeView.Design.dll [modified] Pin
othmane20113-Feb-10 1:41
othmane20113-Feb-10 1:41 
QuestionTreeview Pin
Ch.Gayatri Subudhi19-Mar-09 22:22
Ch.Gayatri Subudhi19-Mar-09 22:22 
Questionneed your advice Pin
hafidz4-Sep-08 15:34
hafidz4-Sep-08 15:34 
AnswerRe: need your advice Pin
Mehfuz Hossain5-Sep-08 5:43
Mehfuz Hossain5-Sep-08 5:43 
Generalcoding Extended TreeView Pin
Phan Thanh Lam10-Mar-08 5:20
Phan Thanh Lam10-Mar-08 5:20 
Generalevent checked in Extended Treeview VB.net 2003 using Javascript Pin
Phan Thanh Lam9-Mar-08 15:51
Phan Thanh Lam9-Mar-08 15:51 
GeneralRe: event checked in Extended Treeview VB.net 2003 using Javascript Pin
Mehfuz Hossain9-Mar-08 20:02
Mehfuz Hossain9-Mar-08 20:02 
Generalcheckbox in ExtendedTreeview! Pin
Phan Thanh Lam3-Oct-07 23:34
Phan Thanh Lam3-Oct-07 23:34 
GeneralRe: checkbox in ExtendedTreeview! Pin
Mehfuz Hossain4-Oct-07 6:11
Mehfuz Hossain4-Oct-07 6:11 
GeneralRe: checkbox in ExtendedTreeview! Pin
Phan Thanh Lam7-Oct-07 2:09
Phan Thanh Lam7-Oct-07 2:09 
GeneralRe: checkbox in ExtendedTreeview! Pin
Mehfuz Hossain7-Oct-07 7:56
Mehfuz Hossain7-Oct-07 7:56 
Generalextendedtreeview Pin
Phan Thanh Lam23-Sep-07 4:33
Phan Thanh Lam23-Sep-07 4:33 
Generalregarding treeview Pin
haasini11-May-07 20:33
haasini11-May-07 20:33 
GeneralRe: regarding treeview Pin
Mehfuz Hossain11-May-07 21:12
Mehfuz Hossain11-May-07 21:12 
Questiontreeview control? Pin
Phan Thanh Lam6-Mar-07 15:07
Phan Thanh Lam6-Mar-07 15:07 
AnswerRe: treeview control? Pin
Mehfuz Hossain10-Mar-07 7:58
Mehfuz Hossain10-Mar-07 7:58 
QuestionHow to build a tree with dynamic construct Pin
chufall6-Oct-05 20:42
chufall6-Oct-05 20:42 
AnswerRe: How to build a tree with dynamic construct Pin
Mehfuz Hossain11-Oct-05 22:25
Mehfuz Hossain11-Oct-05 22:25 
QuestionCan it be used in windows forms Pin
lols20-Jul-05 0:58
lols20-Jul-05 0:58 
AnswerRe: Can it be used in windows forms Pin
Chris Richner20-Sep-05 22:18
Chris Richner20-Sep-05 22:18 
AnswerRe: Can it be used in windows forms Pin
Anonymous21-Sep-05 0:11
Anonymous21-Sep-05 0:11 
GeneralXPathNavigator Pin
User 19428921-Jun-05 4:11
User 19428921-Jun-05 4:11 
GeneralRe: XPathNavigator Pin
Mehfuz Hossain24-Jun-05 18:54
Mehfuz Hossain24-Jun-05 18:54 
GeneralGoo tech, poorly presented Pin
Omar Al Zabir20-Jun-05 22:47
Omar Al Zabir20-Jun-05 22:47 

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.