C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  Update World C++: Сборник GPL QT исходников
  Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Дебетовая карта Home Credit [CPS] RU

 Creating a highly manageable TreeView control using Microsoft Web TreeView control / Custom Controls / ASP. NET


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.


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:

    <company assembly="TreeView.Objects" 
             expanded = "true" >
        <department assembly="TreeView.Objects" 
               expanded = "true" >
           <section assembly="TreeView.Objects" 
                expanded = "false"/>
    </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.

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.

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.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.

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:

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.

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


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.

Дебетовая карта Home Credit [CPS] RU