【发布时间】:2021-10-23 00:19:34
【问题描述】:
我的代码具有扫描根目录并在 TreeView 中显示 txt 文件(例如)的功能:
private TreeNode DirectoryToTreeView(TreeNode parentNode, string path,
string extension = ".txt")
{
var result = new TreeNode(parentNode == null ? path : Path.GetFileName(path));
foreach (var dir in Directory.GetDirectories(path))
{
TreeNode node = DirectoryToTreeView(result, dir);
if (node.Nodes.Count > 0)
{
result.Nodes.Add(node);
}
}
foreach (var file in Directory.GetFiles(path))
{
if (Path.GetExtension(file).ToLower() == extension.ToLower())
{
result.Nodes.Add(Path.GetFileName(file));
}
}
return result;
}
此函数应通过按钮调用,例如:
treeView1.Nodes.Add(DirectoryToTreeView(null, @"C:\Users\Tomer\Desktop\a"));
它显然冻结了用户界面。
我是新手,我在网上搜索过,似乎没有什么与我的问题相关,因为没有人使用递归函数,我不能简单地在整个函数上调用BeginInvoke,因为它没有任何效果。
我应该走什么路?也许将函数更改为使用 while 循环,然后在 if 语句中调用BeginInvoke?在内存中创建一个TreeNode 对象来填充(可能太大)?
【问题讨论】:
-
假设 WinForms。您可以运行获取节点的任务:缓慢的部分是文件枚举。然后您可以等待
[TreeView].SuspendLayout(),等待任务,例如:[TreeView].Nodes.AddRange(await Task.Run(()=> GetTreeNodes([params])))并恢复布局:[TreeView].ResumeLayout(false);。现在 TreeView 仅在任务返回其结果且 UI 未冻结时更新。 -- 标记问题,指定在任何情况下使用的 GUI 框架。 -
小心使用递归方法。如果您使用返回
DirectoryToTreeView()的结果的中间方法可能会更好(这就是我引入GetTreeNodes([params])方法的原因)。 -
感谢您的回答,现在提到它的获胜形式。我不明白这个解决方案如何与这个递归函数一起工作,我应该在哪里调用你提到的每一件事。
-
如前所述,您可以使用一种中间方法(我之前将其命名为
GetTreeNodes()),它将返回您的DirectoryToTreeView()的结果。 -- 您可以从任何异步方法执行第一条注释中描述的代码。它可以是 Button 的Click事件的处理程序,但您可以使用 Form 的Load事件处理程序或覆盖OnLoad()) 等。如果调用方法不是事件处理程序,则它必须是方法返回Task(或Task<TResult>,取决于其角色/实现)。不是void方法。
标签: c# winforms recursion treeview backgroundworker