C#高级:Winform桌面开发中DataGridView的详解(新)

一、数据填充(反射)

1.封装

/// <summary>
/// 渲染DataGridView
/// </summary>
/// <param name="dataGridView">被渲染控件</param>
/// <param name="list">数据集</param>
/// <param name="headtext">字段和展示名称</param>
/// <param name="ButtonList">按钮名称,可为空</param>
private void GetDataGridView<T>(DataGridView dataGridView, List<T> list, List<(Expression<Func<T, object>> fields, string name)> headtext, List<string> ButtonList = null) where T : class
{// 使用 LINQ 通过直接提取表达式来获取字段名称var propertyNames = headtext.Select(x =>x.fields.Body is MemberExpression memberExpr? memberExpr.Member.Name: ((MemberExpression)((UnaryExpression)x.fields.Body).Operand).Member.Name).ToList();//反射获取字段列表var field = typeof(T).GetProperties().Where(x=> propertyNames.Contains(x.Name)).OrderBy(x => propertyNames.Contains(x.Name) ? propertyNames.IndexOf(x.Name) : int.MaxValue).ToList();//设置表头样式和属性dataGridView.AllowUserToAddRows = false;//不允许添加、删除dataGridView.AllowUserToDeleteRows = false;dataGridView.ReadOnly = true;//设置只读dataGridView.RowHeadersVisible = false;//隐藏最左边的空白栏dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;//自适应宽度// 设置表头样式dataGridView.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle{Alignment = DataGridViewContentAlignment.MiddleCenter, // 中间对齐BackColor = Color.LightGray, // 表头背景色ForeColor = Color.Black, // 表头文字颜色Font = new Font("宋体", 10, FontStyle.Bold), // 表头字体};//dataGridView.RowTemplate.Height = 80;//设置行高//设置表头内容(按实体顺序依次设置名字)dataGridView.Columns.Clear();foreach (var item in headtext){dataGridView.Columns.Add(new DataGridViewTextBoxColumn  //增加文字列{DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },//剧中对齐HeaderText = item.name,//中文标题MinimumWidth = 6,Name = field[headtext.FindIndex(x => x == item)].Name,//字段的名字 例如ID NameReadOnly = true,SortMode = DataGridViewColumnSortMode.NotSortable,//不要列头排序,否则无法居中Width = 110});}//设置表头按钮if (ButtonList != null){foreach (var item in ButtonList){//增加按钮(含样式)dataGridView.Columns.Add(new DataGridViewButtonColumn{DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },HeaderText = "操作",//中文标题MinimumWidth = 6,Name = item,ReadOnly = true,SortMode = DataGridViewColumnSortMode.NotSortable,Width = 110});}}//dataGridView.Columns[0].Width = 200; // 手动调节宽度,注意需要注释掉前面的【AutoSizeColumnsMode 自适应宽度】//dataGridView.Columns[1].Width = 200; // 手动调节宽度// dataGridView.Columns[2].Width = 80; // 手动调节宽度// dataGridView.Columns[3].Width = 80; // 手动调节宽度// dataGridView.Columns[4].Width = 80; // 手动调节宽度// dataGridView.Columns[5].Width = 80; // 手动调节宽度// dataGridView.Columns[6].Width = 300; // 手动调节宽度// 清空现有数据dataGridView.Rows.Clear();//添加数据foreach (var item in list){int rowIndex = dataGridView.Rows.Add();foreach (var jtem in field){//添加普通内容数据dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = jtem.GetValue(item);//字段dataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Black;//if (jtem.Name.ToString().Equals("time"))//对特定的字段处理//{//dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = ((DateTime)(jtem.GetValue(item))).ToString("yyyy年MM月dd日");//格式化日期//dataGridView1.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Red;//文字颜色//dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.Yellow;//背景颜色//}//添加按钮数据if (ButtonList != null){int index = 1;foreach (var j in ButtonList){dataGridView.Rows[rowIndex].Cells[j].Value = j;//按钮名称index++;//移除按钮(两步)//if (false)//{//    dataGridView.Rows[rowIndex].Cells["btn1"] = new DataGridViewTextBoxCell();//重新初始化//    dataGridView.Rows[rowIndex].Cells["btn1"].ReadOnly = true;  // 设置为只读//}}}}dataGridView.Rows[rowIndex].Tag = item;//绑定到Tag上方便后续调用}
}

2.使用

private void Form1_Load(object sender, EventArgs e)
{GetDataGridView(dataGridView1,students,new List<(Expression<Func<Student, object>>,string)>{(x => x.StudentId, "学号"),(x => x.StudentName, "姓名"),(x => x.StudentScore, "成绩") },new List<string> { "删除", "修改" });
}

3.效果

二、数据填充(遍历)

暂未写

三、点击按钮获取实体 

1.方法

找到你的 dataGridView1 双击进入 CellClick

双击进去后写代码:

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{if (e.ColumnIndex == dataGridView1.Columns["删除"].Index && e.RowIndex >= 0)//若点击了【删除】按钮{// 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到StudentDorm字段(虽然没有显示在界面上,但整个实体也绑定到Tag了)var item =  dataGridView1.Rows[e.RowIndex].Tag as Student;MessageBox.Show($"展示内容:学生姓名{item.StudentName},分数{item.StudentScore},学生宿舍{item.StudentDorm}", "点击了删除按钮");}
}

2.效果

 四、点击单元格获取实体

 这个和标题三实现起来很相似的

1.方法

找到你的 dataGridView1 双击进入 CellClick

双击进去后写代码:

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{if (e.ColumnIndex == dataGridView1.Columns["StudentName"].Index && e.RowIndex >= 0)//若点击了【姓名】单元格{// 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到StudentDorm字段(虽然没有显示在界面上,但整个实体也绑定到Tag了)var item =  dataGridView1.Rows[e.RowIndex].Tag as Student;MessageBox.Show($"展示内容:学生姓名{item.StudentName},分数{item.StudentScore},学生宿舍{item.StudentDorm}", "点击了【姓名】单元格");}
}

2.效果

五、获取DatagridView列表

1.封装

/// <summary>
/// 获取指定datagridview的列表,并转化为T实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataGridView"></param>
/// <returns></returns>
private List<T> GetDataGridList<T>(DataGridView dataGridView) where T : class
{List<T> list = new List<T>();foreach (DataGridViewRow row in dataGridView.Rows){var item = row.Tag as T;list.Add(item);}return list;
}

2.使用

//点击触发查询列表
private void button1_Click(object sender, EventArgs e)
{var myList = GetDataGridList<Student>(dataGridView1);
}

3.效果

六、列表的编辑

暂未写,需要传出编辑前和编辑后的状态

七、单条数据的编辑(Key=字段,Value=内容)

暂未写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86748.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86748.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人脸活体识别2:Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集)

人脸活体识别2&#xff1a;Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集) 目录 人脸活体识别2&#xff1a;Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集) 1. 前言 2.人脸活体识别方法 &#xff08;1&#xff09;基于人脸动作的检测​​ &a…

Webpack 自定义插件开发指南:构建流程详解与实战开发全攻略

一. webpack打包流程 开发 Webpack 插件的第一步&#xff0c;就是明确&#xff1a;我的插件要接入 Webpack 构建流程的哪个阶段&#xff0c;解决什么问题。 了解流程之前首先要了解插件的两个核心概念&#xff1a;compiler&#xff0c;compilation 1. compiler&#xff1a;全局…

本地部署Dify+Ragflow及使用(一)

概念说明 RAGflow&#xff1a; 吃透知识&#xff1a;将企业文档&#xff08;如技术白皮书&#xff09;解析为结构化知识片段。精准检索&#xff1a;当用户提问时&#xff0c;从知识库中召回最相关内容。 模型供应商&#xff1a; 提供大脑&#xff1a;为 Dify 提供生成答案的模…

2025.06.24【R语言】|clusterProfiler安装与常见报错FAQ全解

文章目录 一、clusterProfiler安装方法1. Bioconductor官方推荐2. Conda安装&#xff08;个人推荐 适合服务器/依赖复杂环境&#xff09;3. 检查安装 二、常见依赖包安装三、常见报错与解决方案1. 报错&#xff1a;could not find function "bitr"2. 报错&#xff1a…

【转】PostgreSql的镜像地址

docker.io/postgres 项目中国可用镜像列表 | 高速可靠的 Docker 镜像资源 docker.io/postgrest/postgrest:v12.2.8 linux/amd64 docker.io17.34MB2025-04-04 13:14 346 docker.io/postgrest/postgrest:v12.2.12 linux/amd64 docker.io17.38MB2025-05-27 22:02 79 docker.io…

爬虫005----Selenium框架

在总结爬虫 &#x1f577; 框架之前&#xff0c;先总结一下selenium框架&#xff0c;也可以说是selenium库&#xff0c;在自动化测试中是老生常谈了&#xff08;长时间⌛️不用&#xff0c;已经忘记了&#xff0c;实际测试工作中做UI自动化的也很少了&#xff0c;上次搞UI自动化…

记一次 Kafka 磁盘被写满的排查经历

开篇扯犊子 今天踏进办公听到不是同事的早安&#xff0c;而是“有一个好消息&#xff0c;一个坏消息&#xff0c;你想听哪个&#xff1f;” 我一愣&#xff0c;心想“大早上&#xff0c;就要玩刺激的吗&#xff1f;” 但是还是淡定的回复说“无所谓&#xff0c;哥什么场面没见…

python多线程:各线程的输出在控制台中同一行原因分析

代码例子 import threading import timedef error_worker():print("子线程开始")time.sleep(1)raise Exception("子线程出错了&#xff01;")t threading.Thread(targeterror_worker) t.start()print("主线程继续执行&#xff0c;不受子线程异常影响…

Promptify与ReActAgent

一、Promptify 定位&#xff1a;NLP 任务的「自动化流水线」 1. 解决什么问题&#xff1f; 传统 LLM 应用开发痛点&#xff1a; 反复调试&#xff1a;需手工编写/调整 prompt 格式&#xff08;如调整分隔符、示例数量&#xff09;兼容性差&#xff1a;不同模型需重写适配代码…

如何将视频从 iPhone 发送到 Android 设备

如果您想将视频从 iPhone 发送到 Android 设备&#xff0c;尤其是视频尺寸较大时&#xff0c;您需要一种高效的传输方法。本文将为您提供 7 种实用方法&#xff0c;让您轻松发送大型视频文件或短视频片段&#xff0c;并且不会损失视频质量。 第 1 部分&#xff1a;如何通过 iRe…

Stable Diffusion入门-ControlNet 深入理解 第四课:风格迁移与重绘控制模型——让AI也有“艺术天赋”!

大家好&#xff0c;欢迎回到 Stable Diffusion入门-ControlNet 深入理解 系列的第四课&#xff01; 如果你还没有看过上一课&#xff0c;赶紧补课哦&#xff1a;Stable Diffusion入门-ControlNet 深入理解 第三课。 上一课我们讲解了 ControlNet 结构类模型&#xff0c;今天我…

国产鸿蒙系统开放应用侧载,能威胁到Windows地位吗?

上个月华为正式发布了 HarmonyOS PC 操作系统&#xff0c;关于生态方面大家其实一直蛮担心。 例如不兼容Windows应用、不支持应用侧载等。 不过&#xff0c;在最近举行的华为开发者大会 2025 电脑分论坛上&#xff0c;华为终端 BG 平板与 PC 产品线总裁&#xff08;朱懂东&am…

Linux登录检查脚本

登录检查脚本 提高兼容性&#xff08;适应不同Linux发行版&#xff09;增强可视化效果和可读性增加关键资源警戒提示优化表格对齐和颜色使用添加系统安全状态检查 #!/bin/bash# 改进版系统登录提示脚本 # 优化点&#xff1a;兼容性增强、资源警戒提示、表格美化、安全状态检查…

jenkinsfile调用groovy

先决条件 gitlab存放jenkinsfile以及groovy代码,jenkins我个人使用的是2.486具体的部署方法自己搞定,一堆文档. gitlab创建一个devops8项目组以及my-jenkins-demo2项目用于演示过程 创建群组 这里已经创建好相关群组. 进入群组创建新项目 创建一个空白项目 配置项目选项 说明…

Ubuntu20.04离线安装Realtek b852无线网卡驱动

最近有个项目&#xff0c;需要在 Ubuntu20.04 LTS 下开发&#xff0c;首先是安装 Linux&#xff0c;我们可以从下面的网址下载&#xff1a; https://releases.ubuntu.com/20.04/ 本以为一切顺利&#xff0c;结果刚开始就给我整不会了。我的电脑是联想设计师GeekPro7&#xff…

1 Studying《Computer Architecture A Quantitative Approach》5-7

目录 5 Thread-Level Parallelism 5.1 Introduction 5.2 Centralized Shared-Memory Architectures 5.3 Performance of Symmetric Shared-Memory Multiprocessors 5.4 Distributed Shared-Memory and Directory-Based Coherence 5.5 Synchronization: The Basics 5.6 M…

融智兴科技: RFID超高频柔性抗金属标签解析

在当今科技飞速发展的时代&#xff0c; RFID技术凭借其独特的优势&#xff0c;在众多领域得到了广泛应用。然而&#xff0c;在金属环境中&#xff0c;传统RFID标签往往面临着诸多挑战&#xff0c;如信号干扰、识别距离短等问题。融智兴科技推出的RFID 超高频柔性抗金属标签&…

PHP Error: 深入解析与解决策略

PHP Error: 深入解析与解决策略 引言 PHP作为世界上最流行的服务器端脚本语言之一,在全球范围内被广泛使用。然而,在PHP的开发过程中,错误处理是一个非常重要的环节。本文将深入探讨PHP错误处理的相关知识,包括错误类型、错误配置、错误日志以及常见的错误解决策略。 PH…

零基础langchain实战二:大模型输出格式化成json

零基础langchain实战一&#xff1a;模型、提示词和解析器-CSDN博客 书接上文 大模型输出格式化 在下面例子中&#xff1a;我们需要将大模型的输出格式化成json。 import os from dotenv import load_dotenvload_dotenv() # 加载 .env 文件 api_key os.getenv("DEEPS…

高通手机跑AI系列之——人脸变化算法

环境准备 手机 测试手机型号&#xff1a;Redmi K60 Pro 处理器&#xff1a;第二代骁龙8移动--8gen2 运行内存&#xff1a;8.0GB &#xff0c;LPDDR5X-8400&#xff0c;67.0 GB/s 摄像头&#xff1a;前置16MP后置50MP8MP2MP AI算力&#xff1a;NPU 48Tops INT8 &&…