2009-07-20 22 views
17

Tôi đang cố gắng để cư một treeview từ một danh sách các đường dẫn thư mục, ví dụ:populate treeview từ một danh sách các đường

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 

với một ouput như thế này:

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

Thông báo có không có 'C: \ WINDOWS \ Microsoft.NET' hoặc 'C: \ WINDOWS \ Microsoft.NET \ Framework' trong danh sách. Tôi đã làm việc này trong gần hai ngày và có một loạt lỗi trong mã của tôi. Hy vọng tôi có thể nhận được sự giúp đỡ từ đây.

Cảm ơn.

Eric

+0

bài .... bạn ... mã .... – womp

+0

Tương tự như [câu hỏi này] (http://stackoverflow.com/questions/673931/file-system-treeview/674119#674119) – PaulB

Trả lời

0

Dưới đây là một số mã rất cũ Tôi đã từng sử dụng để tạo ra một treeview ASP.NET từ mã (giả sử TreeView có một ID của 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; 
} 
-2

Trừ khi bạn gửi mã này, nó không thể xác định những gì sai với nó. Thay vì chi tiêu ngày về vấn đề này tại sao không sử dụng một điều khiển bên thứ 3 như FolderView

26
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

8

ehosca câu trả lời correcr, nhưng có một vấn đề nhỏ, khi tôi thay đổi đường dẫn để thích

này
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 

enter image description here

Nó sẽ popoulate t xem lại như thế này.

Nhưng thêm một số mã phụ, chúng tôi có thể tránh tình trạng này. Vì vậy, tôi đã thay đổi mã trong 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 

      } 
     } 

Bây giờ nó hoạt động tốt như thế này

enter image description here

+1

cảm ơn bạn đã sửa chữa! – ehosca

4

tôi lấy mã của bạn, và nó hoạt động rất tốt, nhưng tôi làm chỉ là một thay đổi nhỏ để cải thiện tốc độ tải khi nó được sử dụng whit một danh sách lớn các tệp có vẻ như hoạt động tìm kiếm và hoạt động chuỗi thường rất chậm

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

sau đó bạn có thể sử dụng:

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, "\\")); 

Chú ý: có thể một số chuỗi kiểm tra sự nhạy cảm sẽ được cần thiết trong cả hai giải pháp, để ngăn chặn một số thư mục tái sáng tạo.

vì một số url có thể trỏ đến cùng một thư mục trên đĩa nhưng được viết khác nhau như: Windows; Windows, Windows

+2

Trình chỉ mục chuỗi của TreeNodeCollection gọi nội bộ IndexOfKey thực hiện tra tuyến tuyến tính của tất cả các nút con cho đến khi khóa được tìm thấy, tiếp theo là IsValidIndex. Tìm mặt khác có thể kiểm soát độ sâu của tìm kiếm bằng tham số searchAllChildren. Tùy thuộc vào cấu trúc dữ liệu của bạn, bạn có thể chọn cách tối ưu. Cả hai đều kết thúc gọi WindowsFormsUtils.SafeCompareStrings cuối cùng. – ehosca

+0

điểm tốt ehosca (y) cảm ơn bạn! – kaytes

8

cho một phiên bản 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; 
} 
0
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; 
    } 
0

Mã này populates điều khiển TreeView của cửa sổ hình thức. Nó đơn giản hơn nhiều so với câu trả lời nhất định.

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); 
     } 
    } 
Các vấn đề liên quan