Click here to Skip to main content
15,887,822 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I'm trying to re-create my AD-structure with treeview.

I have used the example code from the user Smirnov: Active Directory Tree View Emulation | The ASP.NET Forums[^]

A very good example, thank you!

This is my problem:
This code works for the first two levels of treeview but later it becomes complicated for a beginner like me. I have tried to add node position in the OU-name for debugging purposes. Could someone please show me how to do this. :)
I guess I'm trying to solve this problem with the wrong method. There must be a general solution for adding all nodes and all childnodes from Active Directory. Later I will try to add computers also.

AD-structure| Flickr[^]

Application output[^]


using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices;

namespace tree2
{
    public partial class Form1 : Form
    {
        int n = 0;
        int n2 = 0;
        int n3 = 0;
        string server;
        string level1;
        public Form1()
        {
            InitializeComponent();
            server = "LDAP://servername"; 
            level1 = "OU=MyCompany,OU=Companys,dc=my_dc,dc=local";
            GetAllNodes();
            
        }
        private void GetAllNodes()
        {       
            GetNodes(level1, 0);
        }
		
		// Modified code from Smirnov at https://forums.asp.net/post/4381459.aspx
        private void GetNodes(string path, int level)
        {
            using (DirectoryEntry entryToQuery = new DirectoryEntry(server + path))
            {
                DirectorySearcher ouSearch = new DirectorySearcher(entryToQuery);
                ouSearch.Filter = "(objectClass=organizationalUnit)";
                ouSearch.SearchScope = SearchScope.OneLevel;
                ouSearch.PropertiesToLoad.Add("name");

                SearchResultCollection allOUS = ouSearch.FindAll();

                foreach (SearchResult oneResult in allOUS)
                {
                    string ou = oneResult.Properties["name"][0].ToString();
                    string prefix = string.Empty;
                    
                    for (int i = 0; i < level; i++)
                    {
                        prefix += "*";
                    }
                    outbox.AppendText(prefix + ou + Environment.NewLine);
                    
                    int stars = countstars(prefix);
                    if (stars == 0) treeView1.Nodes.Add(ou);
                    if (stars == 1)
                    {
                        treeView1.Nodes[0].Nodes.Add(ou + " 0");
                        n++;
                    }
                    if (stars == 2)
                    {
                        treeView1.Nodes[0].Nodes[n-1].Nodes.Add(ou+" 0." + (n - 1).ToString()); 
                        n2++;
                    }
                    if (stars == 3)
                    {
                        // Not working...
                        // treeView1.Nodes[0].Nodes[n2].Nodes[0].Nodes.Add(ou + " 0." + (n2).ToString() + ".0"); 
                        n3++;
                    }

                    GetNodes("OU=" + ou + "," + path, level + 1);
                    
                }
            }
        }
        int countstars(string a)
        {
            int stars = 0;
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] == '*') stars++;
            }
            return stars;
        }

    }
}


What I have tried:

I have tried different approaches.
* Working with previous, this and next OU and decide where to put it in Treeview.
* I have tried debugging and add some local variables but it gets very messy.
* I have tried with parent node
Posted
Updated 16-Feb-19 15:04pm
Comments
[no name] 16-Feb-19 14:47pm    
You should get all the data first, "look" at it, then load it.

You'll get a better understanding of what's going on and what needs to be done.

It's not call ETL for nothing.
Member 3903277 17-Feb-19 5:12am    
Thank you Gerry!

1 solution

Note: I do not have a network to experiment with. Attached is some generic code to map a text file where the line structure reflects a tree structure with some text-delimiter repeated to indicate node level: note, this is code I wrote some time ago, and does not include robust error-checking; use as is at your own risk.

Suggest you review: [^]

The code here is, imho, simpler, and, I think can be easily adapted by you: [^]

And, CodeProject is your friend: start here: [^]

also see: [^], [^], [^]

Code example:
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace YourNameSpace
{
    public static class StringToTreeView
    {
        private static char[] linesplitter; 

        private static TreeNode node;

        public static Dictionary<int, TreeNode> levelToNode = new Dictionary<int, TreeNode>();

        public static void Map(string source, char linesplit, char levelindicator, ref TreeView tv)
        {
            levelToNode.Clear();

            string[] lines = source.Split(new char[] { linesplit }, StringSplitOptions.RemoveEmptyEntries);

            TreeNode parentNode;

            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];
                string trimmed = line.TrimStart(levelindicator);

                // fast as Linq !
                // https://stackoverflow.com/a/541994/133321
                int level = line.Length - trimmed.Length;

                node = new TreeNode(trimmed);

                levelToNode[level] = node;

                if (level == 0)
                {
                    tv.Nodes.Add(node);
                }
                else 
                {
                    if (levelToNode.TryGetValue(level - 1, out parentNode))
                    {
                        parentNode.Nodes.Add(node);
                    }
                    else
                    {
                        throw new AccessViolationException($"\r\nerror in node definition: level exceeds current use {node.Text}\r\n");
                    }
                }
            }
        }
    }
}
A usage example:
string src = @"one,*two,**three,four,*five,**six,***seven,****eight,**nine";
            StringToTreeView.Map(src, ',', '*', ref YOURTREEVIEW);
 
Share this answer
 
v3
Comments
Member 3903277 17-Feb-19 5:17am    
Thank you so much Bill! This is exactly what I am looking for!! Perfect! Now I can move on with my project. :)

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900