C# 文件系统树视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/673931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File System TreeView
提问by user31849
Im working with file systems and I have a List<> of file objects that have the file path as a property. Basically I need to create a treeview in .NET but im struggling to think of the best way to go about doing this as I need to create a tree structure from a list like:
我使用文件系统,我有一个 List<> 文件对象,这些文件对象将文件路径作为属性。基本上我需要在 .NET 中创建一个树视图,但我正在努力想出最好的方法来做到这一点,因为我需要从一个列表中创建一个树结构,如:
C:/WINDOWS/Temp/ErrorLog.txt
C:/Program Files/FileZilla/GPL.html
C:/Documents and Settings/Administrator/ntuser.dat.LOG
etc....
等等....
The list is not structured at all and I cant make any changes to the current object structure.
该列表根本没有结构化,我无法对当前对象结构进行任何更改。
I'm working in C#.
我在 C# 中工作。
Many thanks for all who contribute
非常感谢所有贡献者
采纳答案by PaulB
If you wanted to stick with the strings something like this would work...
如果你想坚持使用像这样的字符串会起作用......
TreeNode root = new TreeNode();
TreeNode node = root;
treeView1.Nodes.Add(root);
foreach (string filePath in myList) // myList is your list of paths
{
node = root;
foreach (string pathBits in filePath.Split('/'))
{
node = AddNode(node, pathBits);
}
}
private TreeNode AddNode(TreeNode node, string key)
{
if (node.Nodes.ContainsKey(key))
{
return node.Nodes[key];
}
else
{
return node.Nodes.Add(key, key);
}
}
回答by Reed Copsey
I would turn the string into a FileInfo.
我会将字符串转换为 FileInfo。
Once you have the FileInfoobject, you can use the Directory property to retrieve the DirectoryInfofor each path.
拥有FileInfo对象后,您可以使用 Directory 属性来检索每个路径的DirectoryInfo。
Once you have the DirectoryInfo for the path, it's easy to "walk up" the Parent reference in DirectoryInfo to turn each path into a list of directories + filename - ie:
一旦有了路径的 DirectoryInfo,就很容易“走上”DirectoryInfo 中的 Parent 引用,将每个路径转换为目录 + 文件名列表 - 即:
{"C:","Windows","Temp","ErrorLog.txt"}
This should be fairly straightforward to insert into your treeview. Just look for each section of the path in turn, and if it doesn't exist, add it....
这应该相当简单地插入到您的树视图中。只需依次查找路径的每个部分,如果不存在,则添加....
回答by tanascius
give recursion a try.
试试递归。
private void AddFiles()
{
// Iterate your list with FileInfos here
foreach( var fileInfo in new Collection<FileInfo>() )
{
GetOrCreateTreeNode( fileInfo.Directory ).Nodes.Add( new TreeNode( fileInfo.Name ) );
}
}
private TreeNode GetOrCreateTreeNode( DirectoryInfo directory )
{
if( directory.Parent == null )
{
// Access your TreeView control here:
var rootNode = <TreeView>.Nodes[directory.Name];
if( rootNode == null )
{
rootNode = new TreeNode(directory.Name);
// Access your TreeView control here:
<TreeView>.Nodes.Add( rootNode );
}
return rootNode;
}
var parent = GetOrCreateTreeNode( directory.Parent );
var node = parent.Nodes[directory.Name];
if( node == null )
{
node = new DirectoryNode( directory );
parent.Nodes.Add( node );
}
return node;
}
This code should give you only an idea - I have to admit that I did not test it before posting here.
这段代码应该只给你一个想法 - 我不得不承认我在这里发布之前没有测试它。
回答by ehosca
private void Form1_Load(object sender, EventArgs e)
{
var paths = new List<string>
{
@"C:\WINDOWS\AppPatch\MUI0C",
@"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\MUI09"
};
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];
}
}
}
回答by John
EHosca's piece worked for me perfectly, with one change - I had to set lastnode to nothing after the foreach path in paths area.
EHosca 的作品对我来说非常有用,有一个变化 - 在路径区域中的 foreach 路径之后,我必须将 lastnode 设置为空。
This is eHosca's code above, ported to VB.
这是上面 eHosca 的代码,移植到 VB。
Private Sub PopulateTreeView(tv As TreeView, paths As List(Of String), pathSeparator As Char)
Dim lastnode As TreeNode = Nothing
Dim subPathAgg As String
For Each path In paths
subPathAgg = String.Empty
lastnode = Nothing
For Each subPath In path.Split(pathSeparator)
subPathAgg += subPath + pathSeparator
Dim nodes() As TreeNode = tv.Nodes.Find(subPathAgg, True)
If nodes.Length = 0 Then
If IsNothing(lastnode) Then
lastnode = tv.Nodes.Add(subPathAgg, subPath)
Else
lastnode = lastnode.Nodes.Add(subPathAgg, subPath)
End If
Else
lastnode = nodes(0)
End If
Next
Next
End Sub