求助:为MVC 5创建简易TreeView(支持动态/静态数据)
简易MVC TreeView实现(静态+动态数据)
一、静态数据TreeView实现
用原生HTML+CSS+JS就能快速搭建,无需依赖第三方组件:
1. 控制器(HomeController.cs)
在Action中传递模拟的静态文件夹层级数据:
public ActionResult Index() { // 模拟静态文件夹结构 var folders = new List<FolderViewModel> { new FolderViewModel { Name = "根文件夹1", SubFolders = new List<FolderViewModel> { new FolderViewModel { Name = "子文件夹1-1" }, new FolderViewModel { Name = "子文件夹1-2", SubFolders = new List<FolderViewModel> { new FolderViewModel { Name = "孙文件夹1-2-1" } } } } }, new FolderViewModel { Name = "根文件夹2" } }; return View(folders); } // 定义视图模型 public class FolderViewModel { public string Name { get; set; } public List<FolderViewModel> SubFolders { get; set; } = new List<FolderViewModel>(); }
2. 视图(Index.cshtml)
用递归模板渲染层级结构,配合基础的展开/折叠逻辑:
@model List<FolderViewModel> <style> .tree-node { margin-left: 15px; } .folder-icon { cursor: pointer; } .hidden { display: none; } </style> <div class="tree-view"> @foreach (var folder in Model) { @RenderFolder(folder) } </div> @helper RenderFolder(FolderViewModel folder) { <div> <span class="folder-icon">📁 @folder.Name</span> @if (folder.SubFolders.Any()) { <div class="tree-node"> @foreach (var subFolder in folder.SubFolders) { @RenderFolder(subFolder) } </div> } </div> } <script> // 绑定展开/折叠事件 document.querySelectorAll('.folder-icon').forEach(icon => { icon.addEventListener('click', function() { const nextNode = this.nextElementSibling; if (nextNode) { nextNode.classList.toggle('hidden'); } }); }); </script>
二、动态获取真实文件夹数据
如果需要读取服务器上的真实目录结构,只需修改控制器逻辑并通过AJAX加载:
1. 控制器扩展方法
添加读取文件夹层级的逻辑:
public ActionResult GetFolders(string path = @"C:\YourTestDirectory") { var folderModel = GetFolderStructure(path); return Json(folderModel, JsonRequestBehavior.AllowGet); } private FolderViewModel GetFolderStructure(string path) { var directory = new DirectoryInfo(path); var folder = new FolderViewModel { Name = directory.Name }; try { foreach (var subDir in directory.GetDirectories()) { folder.SubFolders.Add(GetFolderStructure(subDir.FullName)); } } catch (UnauthorizedAccessException) { // 处理无权限访问的文件夹 folder.Name += " (无权限)"; } return folder; }
2. 视图修改为AJAX加载
<div class="tree-view" id="tree-container"></div> <style> .tree-node { margin-left: 15px; } .folder-icon { cursor: pointer; } .hidden { display: none; } </style> <script> // 页面加载时请求数据 window.onload = function() { fetch('/Home/GetFolders') .then(response => response.json()) .then(data => { renderFolder(data, document.getElementById('tree-container')); }); }; // 递归渲染文件夹 function renderFolder(folder, parentElement) { const folderDiv = document.createElement('div'); const iconSpan = document.createElement('span'); iconSpan.className = 'folder-icon'; iconSpan.textContent = `📁 ${folder.Name}`; folderDiv.appendChild(iconSpan); if (folder.SubFolders && folder.SubFolders.length > 0) { const subNodeDiv = document.createElement('div'); subNodeDiv.className = 'tree-node'; folder.SubFolders.forEach(subFolder => { renderFolder(subFolder, subNodeDiv); }); folderDiv.appendChild(subNodeDiv); // 绑定展开/折叠事件 iconSpan.addEventListener('click', function() { subNodeDiv.classList.toggle('hidden'); }); } parentElement.appendChild(folderDiv); } </script>
注意:读取服务器文件夹时,需确保应用程序有对应目录的访问权限,测试建议使用安全的测试目录。
内容的提问来源于stack exchange,提问作者Vidyottam
相关产品推荐
相关产品推荐

