21 .net c# vb.net treeview recursive-datastructures
我正在尝试从文件夹路径列表填充树视图,例如:
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
Run Code Online (Sandbox Code Playgroud)
像这样的输出:
????addins
????AppPatch
? ????MUI
? ????040C
????Microsoft.NET
? ????Framework
? ????v2.0.50727
? ????MUI
? ????0409
Run Code Online (Sandbox Code Playgroud)
请注意列表中没有'C:\ WINDOWS\Microsoft.NET'或'C:\ WINDOWS\Microsoft.NET\Framework'.我已经工作了将近两天,我的代码中有一堆bug.希望我能从这里得到帮助.
谢谢.
埃里克
eho*_*sca 27
private void Form1_Load(object sender, EventArgs e)
{
var paths = new List<string>
{
@"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<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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
ykm*_*m29 11
对于linq'y版本:
public static TreeNode MakeTreeFromPaths(List<string> 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<TreeNode>().Where(x => x.Text.Equals(item));
currentNode = tmp.Count() > 0 ? tmp.Single() : currentNode.Nodes.Add(item);
}
}
return rootNode;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
它将像这样流行树视图.
但是添加一些额外的代码我们可以避免这种情况.所以我改变了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
}
}
Run Code Online (Sandbox Code Playgroud)
现在它工作得很好
小智 5
我拿了你的代码,它工作得很好,但我只是做了一点修改,以提高加载速度,当它使用一个大文件列表时,它看起来像查找操作,而字符串操作通常很慢
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;
}
Run Code Online (Sandbox Code Playgroud)
那么你可以使用:
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, "\\"));
Run Code Online (Sandbox Code Playgroud)
注意:可能在两种解决方案中都需要进行一些字符串敏感性检查,以防止重新创建某些文件夹。
因为某些 url 可能指向磁盘上的同一个文件夹,但拼写不同,例如: 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;
}
Run Code Online (Sandbox Code Playgroud)