Member 3903277 Ответов: 1

Как создать treeview, который считывает все узлы/дочерние узлы из active directory?


Привет,

Я пытаюсь воссоздать свою рекламную структуру с помощью treeview.

Я использовал пример кода от пользователя Smirnov: Эмуляция древовидного представления Active Directory | The ASP.NET форумы[^]

Очень хороший пример, спасибо!

Это моя проблема:
Этот код работает для первых двух уровней treeview, но позже он становится сложным для новичка, такого как я. Я попытался добавить позицию узла в OU-name для целей отладки. Не мог бы кто-нибудь показать мне, как это сделать? :)
Наверное, я пытаюсь решить эту проблему неверным методом. Должно быть общее решение для добавления всех узлов и всех дочерних узлов из Active Directory. Позже я также попытаюсь добавить компьютеры.

Рекламная структура| На Flickr[^]

Выход приложения[^]


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;
        }

    }
}


Что я уже пробовал:

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

Gerry Schmitz

Вы должны сначала получить все данные, "посмотреть" на них, а затем загрузить их.

Вы лучше поймете, что происходит и что нужно делать.

Это не зря называется ETL.

Member 3903277

Спасибо тебе, Джерри!

1 Ответов

Рейтинг:
10

BillWoodruff

Примечание: у меня нет сети для экспериментов. Прилагается некоторый общий код для отображения текстового файла, где строчная структура отражает древовидную структуру с некоторым текстовым разделителем, повторяющимся для указания уровня узла: Примечание, это код, который я написал некоторое время назад, и не включает надежную проверку ошибок; Используйте как есть на свой страх и риск.

Предлагаю вам ознакомиться: [^]

Код здесь, имхо, проще и, я думаю, может быть легко адаптирован вами: [^]

И, CodeProject - ваш друг: начните здесь: [^]

также видеть: [^], [^], [^]

Пример кода:

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");
                    }
                }
            }
        }
    }
}
Пример использования:
string src = @"one,*two,**three,four,*five,**six,***seven,****eight,**nine";
            StringToTreeView.Map(src, ',', '*', ref YOURTREEVIEW);


Member 3903277

Большое вам спасибо, Билл! Это именно то, что я ищу!! Прекрасно! Теперь я могу двигаться дальше с моим проектом. :)