我的 Linux PC 上托管着一台服务器。现在我正在创建一个 FTP 客户端,并使用一些特定的工具来处理。现在我想在 Windows 窗体中生成 TreeView。我已经生成了一个树视图,但登录需要太多时间,因为当目录增加时列出所有目录和子目录需要大量时间。我只想加载第一层目录,然后当用户单击展开(“+”)按钮时,它应该填充该目录下的目录并喜欢它。如何做到这一点?我当前的树视图代码如下所示
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows.Forms;
namespace GISFileManagerClient
{
public class TreeView
{
public FtpWebResponse PopulateDirectories(TreeNode parentNode,
string ftpRootPath,
string hostUsername,
string hostPassword,
FtpWebRequest request,
FtpWebResponse response
)
{
try
{
// ftp request for each directory list
request = (FtpWebRequest)WebRequest.Create(ftpRootPath);
request.Credentials = new NetworkCredential(hostUsername, hostPassword);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.KeepAlive = true;
response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string directoryContents = reader.ReadToEnd();
string[] directories = directoryContents.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
List<string> modifiedDirectories = new List<string>();
foreach (string directory in directories)
{
// splitting directory name for refined folder
string[] parts = directory.Split('/');
// getting last string after '/' as that will be present directory "AWGSS/DG" will give DG
string modifiedDirectory = parts[parts.Length - 1];
// refined directories name to remove confusion
modifiedDirectories.Add(modifiedDirectory);
}
// converting list to string array before passing
string[] finalDirectories = modifiedDirectories.ToArray();
foreach (string directory in finalDirectories)
{
// creating node for each directory
Console.WriteLine($"directory looks like this: {directory}");
TreeNode node = new TreeNode(directory);
parentNode.Nodes.Add(node);
Console.WriteLine($"new stream looks like this: {ftpRootPath}/{Path.GetFileName(directory)}");
// condition to differentiate between file and directory
bool isDirectory = Path.GetFileName(directory).Contains(".");
if (isDirectory)
{
continue;
}
else
{
PopulateDirectories(node, $"{ftpRootPath}/{Path.GetFileName(directory)}", hostUsername, hostPassword, request, response);
}
}
reader.Close();
}
catch (WebException ex)
{
// Handle exception
// MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine($"Error: {ex.Message}");
}
return response;
}
}
}
尝试频繁填充树视图目录。
期望在用户单击展开按钮时填充子内容,而不是之前。
实现
TreeView.BeforeExpand
事件以仅在用户展开节点时填充节点:https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.beforeexpand
您还必须确保即使对于尚未访问的节点也显示展开按钮。虽然从技术上讲,底层 Windows 树视图控件确实允许这样做(请参阅
TVIF_CHILDREN
),但此功能似乎并未在 WinForms 中公开。您要么必须使用 P/Invoke 来实现(虽然可行,但工作量很大,因为 API 很复杂),或者只是向尚未填充的节点添加一个假子节点。
相关问题:
您还应该考虑从后台线程填充树,而不是阻塞 GUI 线程。这实际上允许您在后台填充整个树,而不仅仅是在用户展开节点时。但这是另一个问题了。