当前位置: 首页 > news >正文

C# ObjectListView实现树状文件夹浏览

 C# ObjectListView 实现树状图与表格显示文件夹内容详解

概述

在C#桌面应用程序开发中,经常需要展示文件系统的树状结构和详细内容。ObjectListView是一个功能强大的开源.NET控件,它扩展了标准的ListView控件,提供了更多高级功能。本文将介绍如何使用ObjectListView实现树状结构显示文件夹内容,并支持图片预览功能。

环境准备

首先,需要通过NuGet安装必要的依赖包:

Install-Package ObjectListView

核心实现

1. 文件系统数据模型

创建一个表示文件系统项的模型类:

public class MyFileSystemInfo : IEquatable<MyFileSystemInfo>
{public MyFileSystemInfo(FileSystemInfo fileSystemInfo){if (fileSystemInfo == null) throw new ArgumentNullException("fileSystemInfo");this.info = fileSystemInfo;}public bool IsDirectory { get { return this.AsDirectory != null; } }public DirectoryInfo AsDirectory { get { return info as DirectoryInfo; } }public FileInfo AsFile { get { return info as FileInfo; } }private readonly FileSystemInfo info;public string Name { get { return info.Name; } }public string Extension { get { return info.Extension; } }public DateTime CreationTime { get { return info.CreationTime; } }public DateTime LastWriteTime { get { return info.LastWriteTime; } }public string FullName { get { return info.FullName; } }public FileAttributes Attributes { get { return info.Attributes; } }public long Length { get { return this.AsFile != null ? this.AsFile.Length : 0; } }public IEnumerable GetFileSystemInfos(){ArrayList children = new ArrayList();if (this.IsDirectory){foreach (FileSystemInfo x in this.AsDirectory.GetFileSystemInfos())children.Add(new MyFileSystemInfo(x));}return children;}// 实现相等性比较接口public bool Equals(MyFileSystemInfo other){return other != null && Equals(other.info.FullName, this.info.FullName);}public override bool Equals(object obj){return Equals(obj as MyFileSystemInfo);}public override int GetHashCode(){return this.info.FullName.GetHashCode();}
}

2. 初始化树状列表视图

void InitializeTreeListExample()
{// 设置树形列表属性this.treeListView.HierarchicalCheckboxes = true;this.treeListView.HideSelection = true;// 设置节点展开判断逻辑this.treeListView.CanExpandGetter = delegate (object x){return ((MyFileSystemInfo)x).IsDirectory;};// 设置获取子节点逻辑this.treeListView.ChildrenGetter = delegate (object x){MyFileSystemInfo myFileSystemInfo = (MyFileSystemInfo)x;try{return myFileSystemInfo.GetFileSystemInfos();}catch (UnauthorizedAccessException ex){MessageBox.Show(ex.Message, "权限错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);return new ArrayList();}};// 自定义树形连接线样式TreeListView.TreeRenderer renderer = this.treeListView.TreeColumnRenderer;renderer.LinePen = new Pen(Color.Firebrick, 0.5f);renderer.LinePen.DashStyle = DashStyle.Dot;// 设置系统图标SysImageListHelper helper = new SysImageListHelper(this.treeListView);this.treeColumnName.ImageGetter = delegate (object x){return helper.GetImageIndex(((MyFileSystemInfo)x).FullName);};// 设置自定义渲染器this.treeColumnDetail.Renderer = new OperationRenderer();this.treeColumnDelete.Renderer = new OperationRenderer1();// 设置文件类型列this.treeColumnFileType.AspectGetter = delegate (object x){return ShellUtilities.GetFileType(((MyFileSystemInfo)x).FullName);};// 加载根节点string path = "E://Imgs//" + DateTime.Now.ToString("yyyyMMdd");ArrayList roots = new ArrayList();roots.Add(new MyFileSystemInfo(new DirectoryInfo(path)));this.treeListView.Roots = roots;this.treeListView.Refresh();SelectAllNodes(); // 选中所有节点
}

3. 自定义列渲染器

实现操作按钮的自定义渲染:

public class OperationRenderer : BaseRenderer
{private readonly Pen borderPen = new Pen(Color.DarkBlue, 1.5f);private readonly Brush textBrush = new SolidBrush(Color.White);private readonly Brush backgroundBrush = new SolidBrush(Color.FromArgb(70, 130, 180));public override void Render(Graphics g, Rectangle r){var rowData = this.RowObject as MyFileSystemInfo;if (ShouldShowOperation(rowData)){// 绘制按钮背景和边框g.FillRectangle(backgroundBrush, r);g.DrawRectangle(borderPen, r.X, r.Y, r.Width - 1, r.Height - 1);// 绘制文字StringFormat fmt = new StringFormat{Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center};g.DrawString("详情", new Font("微软雅黑", 9, FontStyle.Bold),textBrush, r, fmt);}else{// 清空不满足条件的单元格using (var clearBrush = new SolidBrush(this.ListView.BackColor)){g.FillRectangle(clearBrush, r);}}}// 条件判断逻辑private bool ShouldShowOperation(MyFileSystemInfo data){return data.IsDirectory && data.Name != DateTime.Now.ToString("yyyyMMdd");}
}

4. 图片预览功能

实现点击查看图片详情功能:

private void treeListView_CellClick(object sender, CellClickEventArgs e)
{if (e.Column == this.treeColumnDetail){// 获取绑定的文件系统对象var fileInfo = e.Model as MyFileSystemInfo;if (fileInfo == null) return;// 清空现有图片if (images.Count > 0){foreach (var img in images){img.Dispose();}images.Clear();}// 加载新图片imagePaths = GetImageFiles(fileInfo.FullName);images = new List<Image>();LoadImages();// 显示图片for (int i = 0; i < 4; i++){if (images.Count - 1 >= i){DisplayImage(i);}else{pictureBoxeList[i].Image = defaultImage;}}}else if (e.Column == this.treeColumnDelete){// 删除操作var fileInfo = e.Model as MyFileSystemInfo;if (fileInfo == null) return;if (Directory.Exists(fileInfo.FullName)){try{Directory.Delete(fileInfo.FullName, true);}catch (Exception ex){MessageBox.Show($"删除失败: {ex.Message}");}}RefreshTreeView();}
}// 获取文件夹中的所有图片文件
static List<string> GetImageFiles(string folderPath)
{List<string> imagePaths = new List<string>();if (Directory.Exists(folderPath)){string[] imageExtensions = { "*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff" };foreach (var extension in imageExtensions){string[] files = Directory.GetFiles(folderPath, extension, SearchOption.AllDirectories);imagePaths.AddRange(files);}}return imagePaths;
}

5. 搜索功能

实现按名称搜索文件系统项:

private void BtnSearch_Click(object sender, EventArgs e)
{ArrayList roots = new ArrayList();string targetPath = "E://Imgs//" + DateTime.Now.ToString("yyyyMMdd");if (string.IsNullOrEmpty(TxtCX.Text)){roots.Add(new MyFileSystemInfo(new DirectoryInfo(targetPath)));this.treeListView.Roots = roots;return;}// 获取所有文件系统项var allEntries = GetAllFileSystemEntries(targetPath);ArrayList filteredResults = new ArrayList();// 筛选匹配项foreach (var entry in allEntries){var myInfo = new MyFileSystemInfo(entry);if (myInfo.Name.Contains(TxtCX.Text)){filteredResults.Add(myInfo);}}// 更新树形视图if (filteredResults.Count > 0){this.treeListView.Roots = filteredResults;}this.treeListView.Refresh();
}// 递归获取所有文件系统项
private List<FileSystemInfo> GetAllFileSystemEntries(string rootPath)
{var entries = new List<FileSystemInfo>();try{var rootDir = new DirectoryInfo(rootPath);entries.Add(rootDir);// 递归遍历子目录foreach (var dir in rootDir.EnumerateDirectories("*", SearchOption.AllDirectories)){entries.Add(dir);foreach (var file in dir.EnumerateFiles()){entries.Add(file);}}// 添加根目录文件foreach (var file in rootDir.EnumerateFiles()){entries.Add(file);}}catch (Exception ex){Console.WriteLine($"遍历错误: {ex.Message}");}return entries;
}

界面设计建议

  1. 布局设计

    • 使用SplitContainer将界面分为左右两部分

    • 左侧放置TreeListView显示文件树

    • 右侧放置PictureBox数组用于图片预览

  2. 列配置

    • 名称列:显示文件/文件夹名称和系统图标

    • 类型列:显示文件类型描述

    • 修改时间列:显示最后修改时间

    • 大小列:显示文件大小

    • 操作列:放置详情和删除按钮

  3. 交互设计

    • 支持节点展开/折叠

    • 支持复选框多选

    • 支持点击操作按钮执行相应功能

    • 支持搜索过滤

总结

通过使用ObjectListView控件,我们可以轻松实现一个功能丰富的文件浏览器,具备树形结构展示、多选操作、图片预览等高级功能。本文介绍了核心实现方法,包括数据模型设计、树形列表初始化、自定义渲染器、图片预览和搜索功能。

关键点:

  • 使用MyFileSystemInfo类封装文件系统项

  • 通过CanExpandGetterChildrenGetter实现树形结构

  • 自定义渲染器实现操作按钮

  • 递归遍历文件系统实现搜索功能

  • 使用PictureBox数组实现多图预览

这种实现方式可以广泛应用于文件管理、图片浏览、资源管理等场景,具有良好的扩展性和用户体验。


希望本文对您理解和使用C# ObjectListView控件有所帮助。如有任何问题,欢迎在评论区留言讨论


文章转载自:

http://JNLmQOEZ.bdqpL.cn
http://vaKvLG5h.bdqpL.cn
http://aMsi89eH.bdqpL.cn
http://uR5mzd6C.bdqpL.cn
http://eyWehE3v.bdqpL.cn
http://DhgmE096.bdqpL.cn
http://meMZUwtp.bdqpL.cn
http://TB13R29n.bdqpL.cn
http://UHaDC4lR.bdqpL.cn
http://LMB9rynu.bdqpL.cn
http://ZWcSdbAZ.bdqpL.cn
http://21qkgung.bdqpL.cn
http://7YgwuN3t.bdqpL.cn
http://D7CqKRSo.bdqpL.cn
http://0IdOis2o.bdqpL.cn
http://jHaWnDwq.bdqpL.cn
http://h0Qks12V.bdqpL.cn
http://IfOvHrGw.bdqpL.cn
http://GtWUPNkr.bdqpL.cn
http://W2o42Eh0.bdqpL.cn
http://I1GIBK65.bdqpL.cn
http://9aUvZU8C.bdqpL.cn
http://XQGdcprM.bdqpL.cn
http://CZ6S05kx.bdqpL.cn
http://icpIt9WT.bdqpL.cn
http://FqtjspMb.bdqpL.cn
http://wswEzRJD.bdqpL.cn
http://iPY3cWh2.bdqpL.cn
http://gF4n0a1x.bdqpL.cn
http://1VzdxrSZ.bdqpL.cn
http://www.dtcms.com/a/375074.html

相关文章:

  • 高级 RAG 技术原理和前沿进展
  • 42.Shell脚本判断和if语句及相关案例
  • Game Runtime Libraries Package 解决游戏运行的痛点困境
  • 《P3825 [NOI2017] 游戏》
  • 第三课、Cocos Creator 项目创建与目录结构详解
  • C#中的浅拷贝与深拷贝
  • docker 整理几个常用的指令
  • Git上有更新而本地无更新时的解决方案
  • Doc2X为一切AI文档服务的基础设施,将PDF转换为Word、HTML、LaTeX、Markdown等
  • k8s 内置的containerd配置阿里云个人镜像地址及认证
  • 新节点加入k8s集群命令查看
  • 在 PostgreSQL中查看有哪些用户
  • 【从零开始的大模型原理与实践教程】--第一章:NLP基础概念
  • 零侵入式对接美团核销接口的技术合作模式
  • Kafka面试精讲 Day 14:集群扩容与数据迁移
  • 解耦-IOCDI
  • 【秋招笔试】2025.09.07蚂蚁算法岗笔试题
  • 10月17日,博睿数据受邀出席GOPS 全球运维大会 2025 · 上海站!
  • 第三方软件测评机构:MongoDB分片集群写入吞吐量与延迟第三方性能测评
  • 【硬件-笔试面试题-76】硬件/电子工程师,笔试面试题(知识点:H桥驱动电路的设计要点)
  • 【56页PPT】数字孪生智能工厂总体结构技术架构MES+ERP建设方案(附下载方式)
  • type(类型别名)和 interface的区别和最佳实践
  • 【直流电机鲁棒控制】matlab实现H无穷大控制的直流电机鲁棒控制研究
  • 4 C 语言数据结构实战:栈和队列完整实现(结构体 + 函数)+ 最小栈解决方案
  • day2 java 基础语法
  • Elasticsearch:智能搜索的 MCP
  • 数据结构与算法-树和二叉树-二叉树的存储结构(Binary Tree)
  • OpenCV 图像金字塔
  • 2025年渗透测试面试题总结-61(题目+回答)
  • 传统项目管理和流程管理区别