目录树视图中的延迟加载子文件/文件夹

时间:2016-09-25 04:44:36

标签: c# .net file treeview

我目前正在处理文件浏览控件(https://github.com/gregyjames/FileBrowser),但我遇到了代码性能问题。目前,正如您所看到的here,我有两个递归循环,它们将根目录中的所有文件加载到树视图中。我如何修改它以初始加载根目录中的子文件夹,然后在用户选择时加载每个目录的子目录(即如果用户选择文件夹,然后我加载内容)。任何帮助表示赞赏谢谢!

1 个答案:

答案 0 :(得分:1)

这是我可以想到的延迟加载子节点的最简单/最少量的代码

// Form1.OnLoad 
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    var root = new FolderFileNode(_path);
    treeView1.Nodes.Add(root);
    root.LoadNodes();

    treeView1.BeforeSelect += (sender, args) =>
    {              
        //This flickers a lot , a bit less between BeginUpdate/EndUpdate
        (args.Node as FolderFileNode)?.LoadNodes();                
    };

    treeView1.AfterExpand += (sender, args) =>
    {                
        (args.Node as FolderFileNode)?.SetIcon();                
    };

    treeView1.AfterCollapse += (sender, args) =>
    {
        (args.Node as FolderFileNode)?.SetIcon();                
    };
}                    

class FolderFileNode : TreeNode
{
    private readonly string _path;

    private readonly bool _isFile;

    public FolderFileNode(string path)
    {            
        if(string.IsNullOrWhiteSpace(path)) throw new ArgumentException(nameof(path));
        Text = Path.GetFileName(path);
        _isFile = File.Exists(path);
        _path = path;

        if (!_isFile && Directory.EnumerateFileSystemEntries(_path).Any())
        {
            //Will indicate there is children 
            Nodes.Add(new TreeNode());
        }
        SetIcon();
    }

    public void SetIcon()
    {
        // image[2] is Folder Open image
        ImageIndex = _isFile ? ImageIndex = 1 :  IsExpanded ? 2 : 0;
        SelectedImageIndex = _isFile ? ImageIndex = 1 :  IsExpanded ? 2 : 0;
    }

    private IEnumerable<string> _children;
    public void LoadNodes()
    {
        if (!_isFile && _children == null)
        {
           // _children = Directory.EnumerateFileSystemEntries(_path);
           // Or Add Directories first
           _children = Directory.EnumerateDirectories(_path).ToList();
            ((List<string>) _children).AddRange(Directory.EnumerateFiles(_path)); 

            //Theres one added in the constructor to indicate it has children 
            Nodes.Clear();

            Nodes.AddRange(
                _children.Select(x => 
                    // co-variant
                    (TreeNode) new FolderFileNode(x))
                    .ToArray());
        }
    }
}
相关问题