从路径列表中填充树视图

我正在尝试从文件夹路径列表填充树视图,例如:

C:\WINDOWS\addins C:\WINDOWS\AppPatch C:\WINDOWS\AppPatch\MUI C:\WINDOWS\AppPatch\MUI\040C C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI\0409 

像这样的输出:

 ├───addins ├───AppPatch │ └───MUI │ └───040C ├───Microsoft.NET │ └───Framework │ └───v2.0.50727 │ └───MUI │ └───0409 

请注意列表中没有’C:\ WINDOWS \ Microsoft.NET’或’C:\ WINDOWS \ Microsoft.NET \ Framework’。 我已经工作了将近两天,我的代码中有一堆bug。 希望我能从这里得到帮助。

谢谢。

埃里克

 private void Form1_Load(object sender, EventArgs e) { var paths = new List { @"C:\WINDOWS\AppPatch\MUI\040C", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI", @"C:\WINDOWS\addins", @"C:\WINDOWS\AppPatch", @"C:\WINDOWS\AppPatch\MUI", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI\0409" }; treeView1.PathSeparator = @"\"; PopulateTreeView(treeView1, paths, '\\'); } private static void PopulateTreeView(TreeView treeView, IEnumerable paths, char pathSeparator) { TreeNode lastNode = null; string subPathAgg; foreach (string path in paths) { subPathAgg = string.Empty; foreach (string subPath in path.Split(pathSeparator)) { subPathAgg += subPath + pathSeparator; TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true); if (nodes.Length == 0) if (lastNode == null) lastNode = treeView.Nodes.Add(subPathAgg, subPath); else lastNode = lastNode.Nodes.Add(subPathAgg, subPath); else lastNode = nodes[0]; } } } 

替代文字

ehosca回答correcr,但是当我改变这样的路径时,有一点问题

 C:\WINDOWS\AppPatch\MUI\040C D:\WIS\Microsoft.NET\Framework\v2.0.50727 E:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI C:\WINDOWS\addins C:\WINDOWS\AppPatch C:\WINDOWS\AppPatch\MUI C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI\0409 

在此处输入图像描述

它将像这样流行树视图。

但是添加一些额外的代码我们可以避免这种情况。 所以我改变了PopulateTreeView中的代码

 private static void PopulateTreeView(TreeView treeView, string[] paths, char pathSeparator) { TreeNode lastNode = null; string subPathAgg; foreach (string path in paths) { subPathAgg = string.Empty; foreach (string subPath in path.Split(pathSeparator)) { subPathAgg += subPath + pathSeparator; TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true); if (nodes.Length == 0) if (lastNode == null) lastNode = treeView.Nodes.Add(subPathAgg, subPath); else lastNode = lastNode.Nodes.Add(subPathAgg, subPath); else lastNode = nodes[0]; } lastNode = null; // This is the place code was changed } } 

现在它工作得很好

在此处输入图像描述

对于linq’y版本:

 public static TreeNode MakeTreeFromPaths(List paths, string rootNodeName = "", char separator = '/') { var rootNode = new TreeNode(rootNodeName); foreach (var path in paths.Where(x => !string.IsNullOrEmpty(x.Trim()))) { var currentNode = rootNode; var pathItems = path.Split(separator); foreach (var item in pathItems) { var tmp = currentNode.Nodes.Cast().Where(x => x.Text.Equals(item)); currentNode = tmp.Count() > 0 ? tmp.Single() : currentNode.Nodes.Add(item); } } return rootNode; } 

我拿了你的代码,它运行得很好,但我做了一点修改,以提高加载速度,当它使用大量的文件列表,它似乎找到操作,字符串操作一般很慢

 private TreeNode PopulateTreeNode2(string[] paths, string pathSeparator) { if (paths == null) return null; TreeNode thisnode = new TreeNode(); TreeNode currentnode; char[] cachedpathseparator = pathSeparator.ToCharArray(); foreach (string path in paths) { currentnode = thisnode; foreach (string subPath in path.Split(cachedpathseparator)) { if (null == currentnode.Nodes[subPath]) currentnode = currentnode.Nodes.Add(subPath, subPath); else currentnode = currentnode.Nodes[subPath]; } } return thisnode; } 

然后你可以使用:

 string[] paths = { @"C:\WINDOWS\AppPatch\MUI\040C", @"D:\WINDOWS\Microsoft.NET\Framework\v2.0.50727", @"E:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI", @"C:\WINDOWS\addins", @"C:\WINDOWS\AppPatch", @"C:\WINDOWS\AppPatch\MUI", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI\0409" }; TreeView treeview = new TreeView(); treeview.Nodes.Add(PopulateTreeNode2(paths, "\\")); 

注意:在两种解决方案中都可能需要进行一些字符串灵敏度检查,以防止某些文件夹重新创建。

因为某些url可能指向磁盘上的同一文件夹但拼写不同,例如:Windows; WinDOWs,WINDOWS

这里有一些我用过的代码创建ASP.NET树视图的旧代码(假设TreeView的ID为TreeViewFolders):

 protected void Page_Load(object sender, EventArgs e) { GenerateTreeView(@"C:\WINDOWS\"); } private void GenerateTreeView(string rootPath) { GetFolders(System.IO.Path.GetFullPath(rootPath), TreeViewFolders.Nodes); TreeViewFolders.ExpandDepth = 1; } // recursive method to load all folders and files into tree private void GetFolders(string path, TreeNodeCollection nodes) { // add nodes for all directories (folders) string[] dirs = Directory.GetDirectories(path); foreach (string p in dirs) { string dp = p.Substring(path.Length); nodes.Add(Node("", p.Substring(path.Length), "folder")); } // add nodes for all files in this directory (folder) string[] files = Directory.GetFiles(path, "*.*"); foreach (string p in files) { nodes.Add(Node(p, p.Substring(path.Length), "file")); } // add all subdirectories for each directory (recursive) for (int i = 0; i < nodes.Count; i++) { if (nodes[i].Value == "folder") GetFolders(dirs[i] + "\\", nodes[i].ChildNodes); } } // create a TreeNode from the specified path, text and type private TreeNode Node(string path, string text, string type) { TreeNode n = new TreeNode(); n.Value = type; n.Text = text; return n; } 

此代码填充Windows窗体的TreeView控件。 它比给定答案简单得多。

 using System; using System.Windows.Forms; using System.IO; // ... private void Form1_Load(object sender, EventArgs e) { treeView1.Nodes.Add(@"C:\"); treeView1.Nodes[0].Tag = @"C:\"; Populate((string)treeView1.Nodes[0].Tag, treeView1.Nodes[0]); } private void Populate(string address, TreeNode rootNode) { DirectoryInfo[] directories = new DirectoryInfo(address).GetDirectories(); foreach (DirectoryInfo directory in directories) { TreeNode newNode = new TreeNode(directory.Name); rootNode.Nodes.Add(newNode); newNode.Tag = directory.FullName; try { DirectoryInfo[] innerDirectories = new DirectoryInfo(directory.FullName).GetDirectories(); if (innerDirectories.Length > 0) newNode.Nodes.Add(new TreeNode()); FileInfo[] innerFiles = new DirectoryInfo(directory.FullName).GetFiles(); if (innerFiles.Length > 0) newNode.Nodes.Add(new TreeNode()); } catch { continue; } } FileInfo[] files = new DirectoryInfo(address).GetFiles(); foreach (FileInfo file in files) rootNode.Nodes.Add(file.Name); } private void treeView1_AfterExpand(object sender, TreeViewEventArgs e) { if (e.Node.Nodes.Count < 3) { e.Node.Nodes.Clear(); Populate((string)e.Node.Tag, e.Node); } } 
 private void Form2_Load(object sender, EventArgs e) { treeView1.CheckBoxes = true; foreach (TreeNode node in treeView1.Nodes) { node.Checked = true; } string[] drives = Environment.GetLogicalDrives(); foreach (string drive in drives) { // treeView1.Nodes[0].Nodes[1].Checked = true; DriveInfo di = new DriveInfo(drive); int driveImage; switch (di.DriveType) { case DriveType.CDRom: driveImage = 3; break; case DriveType.Network: driveImage = 6; break; case DriveType.NoRootDirectory: driveImage = 8; break; case DriveType.Unknown: driveImage = 8; break; default: driveImage = 2; break; } TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage); node.Tag = drive; if (di.IsReady == true) node.Nodes.Add("..."); treeView1.Nodes.Add(node); } foreach (TreeNode node in treeView1.Nodes) { node.Checked = true; } } private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e) { { if (e.Node.Nodes.Count > 0) { if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null) { e.Node.Nodes.Clear(); string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString()); foreach (string dir in dirs) { DirectoryInfo di = new DirectoryInfo(dir); TreeNode node = new TreeNode(di.Name, 0, 1); node.Checked = true; try { node.Tag = dir; if (di.GetDirectories().Count() > 0) node.Nodes.Add(null, "...", 0, 0).Checked = node.Checked; } catch (UnauthorizedAccessException) { node.ImageIndex = 12; node.SelectedImageIndex = 12; } catch (Exception ex) { MessageBox.Show(ex.Message, "DirectoryLister", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { node.Checked = e.Node.Checked; e.Node.Nodes.Add(node); } } } } } } private void treeView1_AfterCheck(object sender, TreeViewEventArgs e) { button1.Enabled = false; TreeNode node = e.Node; bool is_checked = node.Checked; foreach (TreeNode childNode in e.Node.Nodes) { childNode.Checked = e.Node.Checked; } treeView1.SelectedNode = node; } 

除非你发布代码,否则无法确定它的错误。 而不是花费数天时间为什么不使用第三方控件,如FolderView