2009-03-23 26 views
8

Im trabajando con sistemas de archivos y tengo una lista <> de objetos de archivos que tienen la ruta del archivo como una propiedad. Básicamente necesito para crear una vista de árbol en .NET, pero estoy luchando para pensar en la mejor manera de ir haciendo esto, ya que necesito para crear una estructura de árbol de una lista como:Sistema de archivos TreeView

C:/WINDOWS/Temp/ErrorLog.txt 
C:/Program Files/FileZilla/GPL.html 
C:/Documents and Settings/Administrator/ntuser.dat.LOG 

etc ....

La lista no está estructurada en absoluto y no puedo realizar ningún cambio en la estructura actual del objeto.

Estoy trabajando en C#.

Muchas gracias por todos los que contribuyen

+0

duplicado Posible de [poblar vista de árbol de una lista de ruta] (http://stackoverflow.com/questions/1155977/populate-treeview-from-a-list-of-path) –

Respuesta

16

Si quería seguir con el cadenas algo como esto iba a funcionar ...

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); 
    } 
} 
+0

es b-e-a-utiful! ¡Muchas gracias señor! – user31849

+0

¿No funciona para Web? ¿Alguien puede ayudarme con esto? –

+0

Impresionante; exactamente lo que necesitaba El único cambio que tuve que hacer fue cambiar 'filePath.Split ('/')' a 'filePath.Split ('/', StringSplitOptions.RemoveEmptyEntries)' para mis propósitos. ¡Gracias! –

4

Me gustaría convertir la cadena en un FileInfo.

Una vez que tenga el objeto FileInfo, puede usar la propiedad Directorio para recuperar el DirectoryInfo para cada ruta.

vez que tenga el DirectoryInfo por el camino, es fácil de "subir" la referencia de los padres en DirectoryInfo para convertir cada ruta en una lista de directorios + nombre de archivo - es decir:

{"C:","Windows","Temp","ErrorLog.txt"} 

Esto debería ser bastante fácil de insertar en su vista de árbol. Solo busque cada sección de la ruta, y si no existe, agréguela ....

2

pruebe la recursión.

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

Este código deberá indicar sólo una idea - Tengo que admitir que no he probado que antes de publicar aquí.

+0

En el método GetOrCreateTreeNode , ¿cuál es la línea de Directories.Nodes [directory.Name] que debe ser? Como no existe tal cosa como Directorios ... ¡Su ayuda hasta ahora es muy apreciada! – user31849

+0

Ver las correcciones - este es el elemento , también – tanascius

+0

Gracias, pensé que sería eso, pero quería asegurarme de que – user31849

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

alt text

+0

-1 Encontré el padre incorrecto en varias situaciones donde la solución de Pablo funcionó. –

0

pieza de EHosca me funcionó a la perfección, con un cambio - que tenía que establecer lastnode to nothing después de la ruta foreach en el área de caminos.

Este es el código de eHosca anterior, portado a 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