C#ListView的单元格支持添加基本及自定义任意控件
功能说明
使用ListView时,希望可以在单元格显示图片或其他控件,发现原生的ListView不支持,于是通过拓展,实现ListView可以显示任意控件的功能,效果如下:

实现方法
本来想着在单元格里面实现控件的自绘的,但是没找到办法,最后是通过在单元格的表面显示对应控件的,浮于表面达到目的。
实现要点如下:
ListView需要设置OwnerDraw=true,并重载自绘函数OnDrawColumnHeader、OnDrawItem、OnDrawSubItem- 支持按单元格添加对应的控件,其
Parent设置为列表ListView - 列表界面调整后,包括大小、列表头、滚动等,需重新绘制单元格的控件
实现源码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace MyListView.Ui
{#region ListViewExpublic class ListViewEx : ListView{#region 内部属性/// <summary>/// 存放单元格控件/// </summary>List<Control> _CellControls = new List<Control>();/// <summary>/// 界面是否发生变化/// </summary>bool IsViewChanged { get; set; }#endregion#region 方法/// <summary>/// 构造函数/// </summary>public ListViewEx(){#region 初始化#endregion#region 事件this.ColumnReordered += ColumnWidthChangedHandler;this.ColumnWidthChanged += ColumnWidthChangedHandler;#endregion}/// <summary>/// 添加控件/// </summary>/// <typeparam name="T"></typeparam>/// <param name="row"></param>/// <param name="col"></param>/// <param name="c"></param>/// <returns></returns>public T Add<T>(int row, int col, T c) where T : Control{if(row >= this.Items.Count || col >= this.Columns.Count){return null;}var index = (row * this.Columns.Count) + col;for (var i = _CellControls.Count; i <= index; i++){_CellControls.Add(null);}var oc = _CellControls[index];if (oc != null){oc.Dispose();}OwnerDraw = true;IsViewChanged = true;c.Parent = this;_CellControls[index] = c;return c;}/// <summary>/// 设置行高度/// </summary>/// <param name="height"></param>public void SetItemHeight(int height){if(this.SmallImageList == null){this.SmallImageList = new ImageList();}this.SmallImageList.ImageSize = new Size(1, height);}#endregion#region 内部函数void ColumnWidthChangedHandler(object s, EventArgs e){IsViewChanged = true;}/// <summary>/// 显示控件到目标单元格/// </summary>/// <param name="c"></param>/// <param name="item"></param>void ShowCellControl(Control c, ListViewItem.ListViewSubItem item){int margin = 2;c.Text = item.Text;c.Visible = true;c.Bounds = new Rectangle(item.Bounds.X + margin,item.Bounds.Top + margin,item.Bounds.Width - 2 * margin,item.Bounds.Height - 2 * margin);}/// <summary>/// 显示单元格控件/// </summary>/// <param name="e"></param>/// <returns></returns>Control GetCellControl(DrawListViewSubItemEventArgs e){Control c = null;#region 获取控件var index = (e.ItemIndex * this.Columns.Count) + e.ColumnIndex;if (index >= _CellControls.Count){return null;}c = _CellControls[index];#endregionreturn c;}protected override void WndProc(ref Message m){#region 事件定义const int WM_SIZE = 0x0005;const int WM_PAINT = 0x000F;const int WM_HSCROLL = 0x114;const int WM_VSCROLL = 0x115;const int WM_MOUSEWHEEL = 0x020A;#endregion#region 重绘显示控件if (m.Msg == WM_PAINT && IsViewChanged){if(this.Columns.Count > 0){for (var i = 0; i < _CellControls.Count; i++){var cell_control = _CellControls[i];if (cell_control == null){continue;}cell_control.Visible = false;var row = i / this.Columns.Count;var col = i % this.Columns.Count;if(row >= Items.Count || col >= this.Columns.Count){continue;}var item = this.Items[row];if(item.Bounds.Y < 0 || item.Bounds.Y >= this.Height){continue;}if(item.SubItems[col].Bounds.X < 0 || item.SubItems[col].Bounds.X >= this.Width){continue;}ShowCellControl(cell_control, item.SubItems[col]);}IsViewChanged = false;}}else if(m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL || m.Msg == WM_SIZE){IsViewChanged = true;}#endregionbase.WndProc(ref m);}protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e){e.DrawDefault = true;}protected override void OnDrawItem(DrawListViewItemEventArgs e){// 已经在OnDrawSubItem处理过了// e.DrawText(TextFormatFlags.Default);}protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e){if(GetCellControl(e) != null){return;}else{e.DrawDefault = true;}}#endregion}#endregion
}
测试代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace MyListView
{public partial class Form1 : Form{#region 函数public Form1(){#region 布局初始化InitializeComponent();var lv = new Ui.ListViewEx(){Dock = DockStyle.Fill,View = View.Details,GridLines = true,};this.Controls.Add(lv);var headers = new string[] { "序号", "名称", "年龄", "住址", "荣誉", "岗位", "头像" };foreach(var v in headers){lv.Columns.Add(v, 100, HorizontalAlignment.Center);}lv.SetItemHeight(40);for(var i=0; i<50; i++){var lvi = lv.Items.Add($"数据{i + 1}");for(var j=1; j<lv.Columns.Count; j++){lvi.SubItems.Add($"数据{i + 1}-{j}");switch(j){case 1:lv.Add(i, j, new Label());break;case 2:lv.Add(i, j, new Button());break;case 3:lv.Add(i, j, new TextBox(){Font = new Font("宋体", 18)});break;case 4:lv.Add(i, j, new ComboBox(){Font = new Font("宋体", 18)});break;case 6:{var pic = lv.Add(i, j, new PictureBox());pic.Image = LoadImage($"logo{i%7}.jpg");pic.SizeMode = PictureBoxSizeMode.StretchImage;}break;}}}#endregion}Image LoadImage(string name){var file = Path.GetFullPath(Path.Combine(@"..\..\Data\IMG", name));if(!File.Exists(file)){return null;}return Image.FromFile(file);}#endregion}
}
相关文章:
C#ListView的单元格支持添加基本及自定义任意控件
功能说明 使用ListView时,希望可以在单元格显示图片或其他控件,发现原生的ListView不支持,于是通过拓展,实现ListView可以显示任意控件的功能,效果如下: 实现方法 本来想着在单元格里面实现控件的自绘的…...
数据库选型实践:如何避开分库分表痛点 | OceanBase用户实践
随着企业业务的不断发展,数据量往往呈现出快速的增长趋势。使用MySQL的用户面对这种增长,普遍选择采用分库分表技术作为应对方案。然而,这一方案常在后期会遇到很多痛点。 分库分表的痛点 痛点 1:难以保证数据一致性。由于分库分…...
3个火火火的AI项目,开源了!
友友们,今天我要给你们安利三个超酷的开源项目,它们都和AI有关,而且每一个都能让你的日常生活变得更加有趣和便捷!(最近AI绘图又又超神了,分享以下美图养眼) 01 字节出品,文字转语音Seed-TTS 字节推出了一…...
算法 | 子集数排列树满m叉树二分搜索归并排序快速排序
子集树:O(2^n) 一个序列的所有子集为2^n,即可看成具有2^n个叶节点的满二叉树 int backtrack(int k) //k表示扩展结点在解空间树中所处的层次 {if(k>n) //n标识问题的规模output(x); //x是存放当前解的一维数组if(constraint(k)…...
SpringBoot配置第三方专业缓存技术jetcache方法缓存方案
jetcache方法缓存 我们可以给每个方法配置缓存方案 JetCache 是一个基于 Java 的缓存库,支持多种缓存方案和缓存策略,主要用于提升应用程序的性能和响应速度。它提供了多种缓存模式和特性,可以根据需求选择合适的缓存方案。 JetCache 的主…...
游戏开发丨基于PyGame的消消乐小游戏
文章目录 写在前面PyGame消消乐注意事项系列文章写在后面 写在前面 本期内容:基于pygame实现喜羊羊与灰太狼版消消乐小游戏 下载地址:https://download.csdn.net/download/m0_68111267/88700193 实验环境 python3.11及以上pycharmpygame 安装pygame…...
软件项目管理概述
1.什么是项目? 2.项目管理的定义 3.项目管理的本质 4.项目成功的标志 5.项目管理的基本方法 6.项目的生命周期(启动 计划 执行 控制 结束) 7.结合生活中的某件事,谈谈项目管理的作用 项目管理在日常生活中扮演着重要的角色&…...
FastAdmin后台开发框架 lang 任意文件读取漏洞复现
0x01 产品简介 FastAdmin是一款基于PHPBootstrap的开源后台框架,专为开发者精心打造。它基于ThinkPHP和Bootstrap两大主流技术构建,拥有完善的权限管理系统和一键生成CRUD等强大功能。FastAdmin致力于提高开发效率,降低开发成本,…...
数字时代PLM系统的重要性
什么是 PLM(产品生命周期管理)? 从最基本的层面上讲,产品生命周期管理 (PLM)是管理产品从最初构思、开发、服务和处置的整个过程的战略流程。换句话说,PLM 意味着管理产品从诞生到消亡所涉及的一切。 什么是 PLM 软件…...
安卓实现圆形按钮轮廓以及解决无法更改按钮颜色的问题
1.实现按钮轮廓 在drawable文件新建xml文件 <shape xmlns:android"http://schemas.android.com/apk/res/android"<!--实现圆形-->android:shape"oval"><!--指定内部的填充色--><solid android:color"#FFFFFF"/><!-…...
常用原语介绍
1.在Xilinx的example(wavegen example)中看到他们的顶层模块的输入输出管脚都手动例化原语IBUF以及OBUF——工具也会自动给我们加上不必要自己加 2.非mrcc个srcc的管脚输入的时钟信号,无法进入mmcm和bufg————试验过会报错 3.实际上&…...
29. 透镜阵列
导论: 物理传播光学(POP)不仅可以用于简单系统,也可以设计优化复杂的光学系统,比如透镜阵列。 设计流程: 透镜阵列建模 在孔径类型中选择“入瞳直径”,并输入2 在视场设定中。设置一个视场&…...
深入理解并打败C语言难关之一————指针(3)
前言: 昨天把指针最为基础的内容讲完了,并且详细说明了传值调用和传址调用的区别(这次我也是做到了每日一更,感觉有好多想写的但是没有写完),下面不多废话,下面进入本文想要说的内容 目录&#…...
Ubuntu-24.04-live-server-amd64启用ssh
系列文章目录 Ubuntu-24.04-live-server-amd64安装界面中文版 Ubuntu安装qemu-guest-agent Ubuntu乌班图安装VIM文本编辑器工具 文章目录 系列文章目录前言一、输入安装命令二、使用私钥登录(可选)1.创建私钥2.生成三个文件说明3.将公钥复制到服务器 三…...
Leetcode 2786. 访问数组中的位置使分数最大(DP 优化)
Leetcode 2786. 访问数组中的位置使分数最大 DP 以每个位置为结尾的序列的分数取决于前方的分数,根据奇偶性计算,取最大值 超时 class Solution {public long maxScore(int[] nums, int x) {int n nums.length;long dp[] new long[n];Arrays.fill(dp…...
【docker实战】使用Dockerfile的COPY拷贝资源遇到的问题
事情是这样的。 在我负责的golang项目中,使用硬代码验证某块逻辑。比如: 于是,为了解决硬代码的问题,我制作了表格工具:【开源项目】Excel数据表自动生成工具v1.0版 – 经云的清净小站 (skycreator.top)。 使用表格工…...
如何用多线程执行 unittest 测试用例实现方案
前言 使用python做过自动化测试的小伙伴,想必都知道unittest和pytest这两个单元测试框架,其中unittest是python的官方库,功能相对于pytest来要逊色不少,但是uniitest使用上手简单,也受到的很多的小伙伴喜爱。一直以来都…...
Ascend310 EP模式下容器内进行推理测试
EP模式下容器内进行推理测试 本文的软硬件环境如下: 机器:x86台式机一台 OS: 5.4.0-26-generic Ubuntu20.04 LTS 推理卡:DLAP200-HP-2(凌华基于atlas200模块打造的两模块推理卡) 1. 推理卡固件和驱动安…...
(el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
Ⅰ、Element-plus 提供的Select选择器组件与想要目标情况的对比: 1、Element-plus 提供Select组件情况: 其一、Element-ui 自提供的Select代码情况为(示例的代码): // Element-plus 提供的组件代码: <template><div class"f…...
Java基础之Math与Array类与System
文章目录 一、Math.random()二、Arrays.binarySearch()三、asList()四、System tip:以下是正文部分 一、Math.random() a < num < b int num (int)(Math.random() * (b - a 1)) a二、…...
【人生底稿 28】新疆出差终章:几番波折终汇报,尽兴踏归津门路
三日游玩尽数落幕,忙碌工作正式回归。轻松的闲暇时光悄然收尾,紧绷的工作状态再次上线。整趟新疆之行,在起伏辗转中迎来最终收尾。一、深夜复盘材料,彻夜待汇报游玩结束回到酒店,我没有松懈休息,静下心重新…...
安全聚合技术:原理、实现与多场景应用
1. 安全聚合技术概述安全聚合(Secure Aggregation)是一种多方安全计算技术,它允许多个互不信任的参与方在不泄露各自私有数据的前提下,共同计算出一个聚合结果。这项技术的核心价值在于解决了数据隐私与数据共享之间的矛盾&#x…...
在线Graphviz图表编辑器:3步创建专业技术流程图
在线Graphviz图表编辑器:3步创建专业技术流程图 【免费下载链接】GraphvizOnline Lets Graphviz it online 项目地址: https://gitcode.com/gh_mirrors/gr/GraphvizOnline 还在为复杂的技术图表绘制而烦恼吗?GraphvizOnline作为一款革命性的在线G…...
UEFITool深度解析:实战指南与高效使用技巧
UEFITool深度解析:实战指南与高效使用技巧 【免费下载链接】UEFITool UEFI firmware image viewer and editor 项目地址: https://gitcode.com/gh_mirrors/ue/UEFITool UEFITool是一款专为UEFI固件分析设计的开源工具,能够将复杂的二进制固件映像…...
NS-USBLoader:Switch游戏管理终极指南 - 如何实现一键安装与系统引导?
NS-USBLoader:Switch游戏管理终极指南 - 如何实现一键安装与系统引导? 【免费下载链接】ns-usbloader Awoo Installer and GoldLeaf uploader of the NSPs (and other files), RCM payload injector, application for split/merge files. 项目地址: ht…...
基于RAG的智能知识库问答系统:从原理到部署实战
1. 项目概述:当AI大模型遇见知识库,一个开源的智能问答解决方案 最近在折腾一个很有意思的开源项目,叫 zhimaAi/chatwiki 。光看名字,你大概能猜到它的核心: chat 代表对话, wiki 代表知识库。没错&a…...
柔性3D打印与生物仿生设计:从TPU材料到空气喷涂的完整实践
1. 项目概述:当柔性3D打印遇上生物仿生美学如果你和我一样,玩3D打印玩久了,总会对那些千篇一律的硬质塑料件感到一丝审美疲劳。我们总在追求更高的精度、更强的结构,却常常忽略了材料本身可以带来的、截然不同的体验。直到我开始接…...
三维重建下半场,拼的全是底层基建实力!
三维重建已从算法创新竞赛正式迈入基础设施比拼新阶段,主流技术路线逐步收敛,单纯算法红利见顶,行业竞争核心转向数据、算力、平台、生态等底层综合能力。当下竞争不再只比模型效果,而是聚焦四大核心基建维度:采集传感…...
3分钟快速上手:ESP32 Arduino开发环境完整配置指南
3分钟快速上手:ESP32 Arduino开发环境完整配置指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 想在熟悉的Arduino环境中开发强大的ESP32物联网项目吗&…...
5分钟学会创建专业交通网络可视化地图
5分钟学会创建专业交通网络可视化地图 【免费下载链接】transit-map The server and client used in transit map simulations like swisstrains.ch 项目地址: https://gitcode.com/gh_mirrors/tr/transit-map 你想在网页上展示动态的公共交通网络吗?Transit…...
