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

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.lqws.cn/news/521047.html

相关文章:

  • 在 GitLab CI 中配置多任务
  • Tomcat
  • 用Rust写平衡三进制乘法器
  • Hoare逻辑与分离逻辑:从程序验证到内存推理的演进
  • ES10(ES2019)新特性整理
  • 华为运维工程师面试题(英语试题,内部资料)
  • mysql 5.1 升级 mysql 5.7 升级 mariadb10
  • RabbitMq中使用自定义的线程池
  • 基于R语言的亚组分析与森林图绘制1
  • 微算法科技融合Grover算法与统一哈希函数的混合经典-量子算法技术,可在多领域高效提升文本处理效率
  • win11搭建Python开发环境指南
  • MAC、IP地址、TCP、UDP、SSL、OSI模型
  • 【MCP 实战4-1】开发 OpenSearch MCP server
  • 南北差异之——理解业务和理解产品
  • spring项目启动sheel脚本
  • 惯性导航——陀螺仪
  • 解决git pull,push 每次操作输入账号密码问题
  • 基于STM32的个人健康助手的设计
  • 鸿蒙应用开发中的数据存储:SQLite与Preferences全面解析
  • 基于 opencv+yolov8+easyocr的车牌追踪识别
  • Kotlin 协程:全面解析与深度探索
  • 工业“三体”联盟:ethernet ip主转profinet网关重塑设备新规则
  • python哈尔滨中心医院用户移动端
  • Docker安装教程-linux
  • LinkAOS网上开户系统解析与开发实践
  • 初学python的我开始Leetcode题10-3
  • 2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(二)
  • 掌握CIS基准合规性:通过自动化简化网络安全
  • 【Lua 基础学习】
  • P2840 纸币问题 2(动态规划)