Bootstrap

转载:C#高级:Winform桌面开发中DataGridView的详解 转载

目录

一、前端界面

二、模块代码

1.初始化列表代码

2.点击单元格按钮事件(datagridview双击进入)

3.一键选中(checkbox)双击进入

 4.查看选中(button)双击进入

5.点击按钮获取选中的一行实体

6.点击单元格获取实体

 7.点击单元行头获取实体

8.获取数据列表

9.列头居中对齐的方法

三、整体代码

四、测试结果

五、样式

六、高度封装的数据填充方法

七、高度封装的分页方法

八、高度封装的单实体修改方法

九、小结


一、前端界面

添加的datagridview应该如下设置:

1.只设置启用编辑

2.设置好每列的名称、控件类型、提示中文(页眉文本),选择【可见】等选项(建议TextBox选可见+只读,Checkbox选可见即可,Button选可见即可。选择只读后,不能被编辑或选中。)

3.如果不需要默认列,可以设置:RowHeadersVisibed = False 

二、模块代码

【实体列表】

1.初始化列表代码

【备注】1.建立列表是模拟查数据库。2.“如果学生名为"小苏",则移除查看详情按钮”是一个题目要求,实际中不需要该功能可注释掉该代码。3.数据实体绑定于Tag上,Tag能识别哪行被点击或选中。


  
  
  1. /// <summary>
  2. /// 初始化填充数据
  3. /// </summary>
  4. /// <param name="sender"></param>
  5. /// <param name="e"></param>
  6. private void Form1_Load(object sender, EventArgs e)
  7. {
  8. #region 建立列表
  9. Student student1 = new Student { ID = 1, Name = "小苏", Remarks = "小苏的备注" };
  10. Student student2 = new Student { ID = 2, Name = "小明", Remarks = "小明的备注" };
  11. Student student3 = new Student { ID = 3, Name = "小花", Remarks = "小花的备注" };
  12. var list = new List<Student>();
  13. list.Add(student1);
  14. list.Add(student2);
  15. list.Add(student3);
  16. #endregion
  17. // 清空现有数据
  18. dataGridView1.Rows.Clear();
  19. //添加数据
  20. foreach ( var item in list)
  21. {
  22. int rowIndex = dataGridView1.Rows.Add();
  23. dataGridView1.Rows[rowIndex].Cells[ "ID"].Value = item.ID; //字段
  24. dataGridView1.Rows[rowIndex].Cells[ "StuName"].Value = item.Name; //字段
  25. dataGridView1.Rows[rowIndex].Cells[ "Details"].Value = "查看详情"; //按钮名称
  26. dataGridView1.Rows[rowIndex].Tag = item;
  27. // 如果学生名为"小苏",则移除查看详情按钮
  28. if (item.Name == "小苏")
  29. {
  30. dataGridView1.Rows[rowIndex].Cells[ "Details"] = new DataGridViewTextBoxCell(); //重新初始化
  31. dataGridView1.Rows[rowIndex].Cells[ "Details"].ReadOnly = true; // 设置为只读
  32. }
  33. }
  34. }
代码解读

【扩展】也可以直接选择绑定而不写上述代码:(灵活性降低)

2.点击单元格按钮事件(datagridview双击进入)

作用:点击查看详情跳出备注信息


  
  
  1. /// <summary>
  2. /// 点击查看详情
  3. /// </summary>
  4. /// <param name="sender"></param>
  5. /// <param name="e"></param>
  6. private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
  7. {
  8. if (e.ColumnIndex == dataGridView1.Columns[ "Details"].Index && e.RowIndex >= 0) //若点击了标签为【Details】列的按钮
  9. {
  10. // 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到Remarks字段(虽然没有显示在界面上,但也绑定到Tag了)
  11. var item = dataGridView1.Rows[e.RowIndex].Tag as Student;
  12. //将list实体中的Remarks展示出来(item包含的字段:ID,Name,Remarks)
  13. MessageBox.Show(item.Remarks, "内容详情");
  14. //【补充一:获取按钮上的文字】
  15. }
  16. }
代码解读

dataGridView1_CellClick比dataGridView1_CellContentClick更加灵敏!

前者是点击单元格触发后者是点击单元格的文字才触发! 

【补充一:获取按钮上的文字】


  
  
  1. DataGridViewButtonCell buttonCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell; //获取点击的按钮
  2. if (buttonCell != null && buttonCell.Value != null)
  3. {
  4. if (buttonCell.Value.ToString() == "借出") //按钮字样为借出
  5. {
  6. ; // 执行借出操作
  7. }
  8. else if (buttonCell.Value.ToString() == "归还") //按钮字样为归还
  9. {
  10. ; // 执行归还操作
  11. }
  12. }
代码解读

3.一键选中(checkbox)双击进入

作用:点击一键选中按钮,选中列表所有的checkbox


  
  
  1. /// <summary>
  2. /// 一键选中
  3. /// </summary>
  4. /// <param name="sender"></param>
  5. /// <param name="e"></param>
  6. private void checkBox1_CheckedChanged(object sender, EventArgs e)
  7. {
  8. if(checkBox1.Checked)
  9. {
  10. foreach (DataGridViewRow row in dataGridView1.Rows)
  11. {
  12. DataGridViewCheckBoxCell checkBox = row.Cells[ "ManySelect"] as DataGridViewCheckBoxCell; //获取【ManySelect】的checkbox列
  13. if (checkBox != null)
  14. {
  15. checkBox.Value = true;
  16. }
  17. }
  18. }
  19. }
代码解读

 4.查看选中(button)双击进入

作用:点击查看选中按钮,获得一个选中的列表

方法一:


  
  
  1. /// <summary>
  2. /// 点击查看选中
  3. /// </summary>
  4. /// <param name="sender"></param>
  5. /// <param name="e"></param>
  6. private void button1_Click(object sender, EventArgs e)//点击触发
  7. {
  8. //获取【DataGridView1】的checkbox选中的实体
  9. var selectlist = new List<Student>(); //将【Student】类存放入列表
  10. //遍历获取数据
  11. foreach (DataGridViewRow row in dataGridView1.Rows)
  12. {
  13. DataGridViewCheckBoxCell checkBox = row.Cells[ "ManySelect"] as DataGridViewCheckBoxCell;
  14. if (checkBox != null && checkBox.Value != null && ( bool)checkBox.Value)
  15. {
  16. // 获取与选中CheckBox相关联的实体,假设实体类型为Student
  17. var entity = row.Tag as Student; //【Student】实体
  18. if (entity != null)
  19. {
  20. selectlist.Add(entity);
  21. }
  22. }
  23. }
  24. //后续可对selectlist操作
  25. }
代码解读

方法二:(获取单一内容)


  
  
  1. private void button3_Click(object sender, EventArgs e)
  2. {
  3. // 创建一个列表来存储选中的内容
  4. List< string> selectedContents = new List< string>();
  5. // 遍历所有行
  6. foreach (DataGridViewRow row in dataGridView1.Rows)
  7. {
  8. // 检查该行是否被选中
  9. if (Convert.ToBoolean(row.Cells[ "Select"].Value) == true)
  10. {
  11. // 获取 "Content" 列的值,并添加到列表中
  12. string contentValue = row.Cells[ "Content"].Value.ToString();
  13. selectedContents.Add(contentValue);
  14. }
  15. }
  16. // 显示选中的内容(可以根据需要进行其他处理)
  17. MessageBox.Show( string.Join( ", ", selectedContents));
  18. }
代码解读

5.点击按钮获取选中的一行实体

前提条件:需要默认列,可以设置 RowHeadersVisibed = True ,即获取点击单元行头的实体


  
  
  1. private void button3_Click(object sender, EventArgs e)
  2. {
  3. if (dataGridView2.SelectedRows.Count == 1) //当选中了一行时
  4. {
  5. // 获取选中的那行,转化为【StuMessage】实体
  6. var selectedEntity = dataGridView2.Rows[dataGridView2.SelectedRows[ 0].Index].Tag as StuMessage;
  7. ;
  8. }
  9. }
代码解读

6.点击单元格获取实体


  
  
  1. private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
  2. {
  3. var stumodel = dataGridView2.Rows[e.RowIndex].Tag as StuMessage;
  4. }
代码解读


  
  
  1. //如果单纯获取点击的内容:
  2. string clickedContent = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
代码解读

 7.点击单元行头获取实体


  
  
  1. private void dataGridView2_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
  2. {
  3. var stumodel = dataGridView2.Rows[e.RowIndex].Tag as StuMessage;
  4. }
代码解读

8.获取数据列表

  封装方法


  
  
  1. /// <summary>
  2. /// 获取指定datagridview的列表,并转化为T实体
  3. /// </summary>
  4. /// <typeparam name="T"></typeparam>
  5. /// <param name="dataGridView"></param>
  6. /// <returns></returns>
  7. private List<T> GetDataGridList<T>(DataGridView dataGridView) where T : class
  8. {
  9. List<T> list = new List<T>();
  10. foreach (DataGridViewRow row in dataGridView.Rows)
  11. {
  12. var item = row.Tag as T;
  13. list.Add(item);
  14. }
  15. return list;
  16. }
代码解读

调用方法:请将Notice替换为您的实体

var list = GetDataGridList<Notice>(dataGridView1);
  
  
代码解读

9.列头居中对齐的方法

三、整体代码

【注意】此代码为Demo代码,并不符合编写规范,旨在帮助开发者找到灵感。


  
  
  1. using System.Collections.Generic;
  2. namespace WinFormsApp2
  3. {
  4. public partial class Form1 : Form
  5. {
  6. public Form1()
  7. {
  8. InitializeComponent();
  9. }
  10. class Student
  11. {
  12. public int ID { get; set; }
  13. public string Name { get; set; }
  14. public string Remarks { get; set; }
  15. }
  16. /// <summary>
  17. /// 初始化填充数据
  18. /// </summary>
  19. /// <param name="sender"></param>
  20. /// <param name="e"></param>
  21. private void Form1_Load(object sender, EventArgs e)
  22. {
  23. #region 建立列表
  24. Student student1 = new Student { ID = 1, Name = "小苏", Remarks = "小苏的备注" };
  25. Student student2 = new Student { ID = 2, Name = "小明", Remarks = "小明的备注" };
  26. Student student3 = new Student { ID = 3, Name = "小花", Remarks = "小花的备注" };
  27. var list = new List<Student>();
  28. list.Add(student1);
  29. list.Add(student2);
  30. list.Add(student3);
  31. #endregion
  32. // 清空现有数据
  33. dataGridView1.Rows.Clear();
  34. //添加数据
  35. foreach ( var item in list)
  36. {
  37. int rowIndex = dataGridView1.Rows.Add();
  38. dataGridView1.Rows[rowIndex].Cells[ "ID"].Value = item.ID; //字段
  39. dataGridView1.Rows[rowIndex].Cells[ "StuName"].Value = item.Name; //字段
  40. dataGridView1.Rows[rowIndex].Cells[ "Details"].Value = "查看详情"; //按钮名称
  41. dataGridView1.Rows[rowIndex].Tag = item;
  42. // 如果学生名为"小苏",则移除查看详情按钮
  43. if (item.Name == "小苏")
  44. {
  45. dataGridView1.Rows[rowIndex].Cells[ "Details"] = new DataGridViewTextBoxCell(); //重新初始化
  46. dataGridView1.Rows[rowIndex].Cells[ "Details"].ReadOnly = true; // 设置为只读
  47. }
  48. }
  49. }
  50. /// <summary>
  51. /// 点击查看选中
  52. /// </summary>
  53. /// <param name="sender"></param>
  54. /// <param name="e"></param>
  55. private void button1_Click(object sender, EventArgs e)//点击触发
  56. {
  57. //获取【DataGridView1】的checkbox选中的实体
  58. var selectlist = new List<Student>(); //将【Student】类存放入列表
  59. //遍历获取数据
  60. foreach (DataGridViewRow row in dataGridView1.Rows)
  61. {
  62. DataGridViewCheckBoxCell checkBox = row.Cells[ "ManySelect"] as DataGridViewCheckBoxCell;
  63. if (checkBox != null && checkBox.Value != null && ( bool)checkBox.Value)
  64. {
  65. // 获取与选中CheckBox相关联的实体,假设实体类型为Student
  66. var entity = row.Tag as Student; //【Student】实体
  67. if (entity != null)
  68. {
  69. selectlist.Add(entity);
  70. }
  71. }
  72. }
  73. //后续可对selectlist操作
  74. }
  75. /// <summary>
  76. /// 点击查看详情
  77. /// </summary>
  78. /// <param name="sender"></param>
  79. /// <param name="e"></param>
  80. private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
  81. {
  82. if (e.ColumnIndex == dataGridView1.Columns[ "Details"].Index && e.RowIndex >= 0) //若点击了标签为【Details】列的按钮
  83. {
  84. // 获取当前行对应的实体对象【注意修改此处Student类】,此处能获取到Remarks字段(虽然没有显示在界面上,但也绑定到Tag了)
  85. var item = dataGridView1.Rows[e.RowIndex].Tag as Student;
  86. //将list实体中的Remarks展示出来(item包含的对象:ID,Name,Remarks)
  87. MessageBox.Show(item.Remarks, "内容详情");
  88. }
  89. }
  90. /// <summary>
  91. /// 一键选中
  92. /// </summary>
  93. /// <param name="sender"></param>
  94. /// <param name="e"></param>
  95. private void checkBox1_CheckedChanged(object sender, EventArgs e)
  96. {
  97. if(checkBox1.Checked)
  98. {
  99. foreach (DataGridViewRow row in dataGridView1.Rows)
  100. {
  101. DataGridViewCheckBoxCell checkBox = row.Cells[ "ManySelect"] as DataGridViewCheckBoxCell; //获取【ManySelect】多选框列
  102. if (checkBox != null)
  103. {
  104. checkBox.Value = true;
  105. }
  106. }
  107. }
  108. }
  109. }
  110. }
代码解读

四、测试结果

1.通过debug发现选中有效(测试通过)

2.发现小苏对应按钮被删除(测试通过)

3.发现一键多选奏效(测试通过,图略) 

4.发现查看详情有效(测试通过)

五、样式

修改某行的字体颜色:


  
  
  1. if (item.Name == "小明")
  2. {
  3. dataGridView1.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Red; //文字颜色
  4. dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.Yellow; //背景颜色
  5. }
代码解读

六、高度封装的数据填充方法

【封装方法】


  
  
  1. /// <summary>
  2. /// 获取DataGridView,需传入控件、数据列表、标题列表
  3. /// </summary>
  4. /// <typeparam name="T"></typeparam>
  5. /// <param name="dataGridView"></param>
  6. /// <param name="list"></param>
  7. /// <param name="headtext"></param>
  8. /// <exception cref="Exception"></exception>
  9. private void GetDataGridView<T>(DataGridView dataGridView,List<T> list,List<string> headtext) where T : class
  10. {
  11. //设置表头样式和属性
  12. dataGridView.AllowUserToAddRows = false; //不允许添加、删除
  13. dataGridView.AllowUserToDeleteRows = false;
  14. dataGridView.ReadOnly = true; //设置可读
  15. dataGridView.RowHeadersVisible = false; //隐藏最左边的空白栏
  16. dataGridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //表头居中对齐
  17. dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; //自适应宽度
  18. //dataGridView.RowTemplate.Height = 80;//设置行高
  19. //获取字段列表
  20. var field = typeof(T).GetProperties();
  21. //判断输入标题
  22. if (headtext.Count != field.Length)
  23. {
  24. throw new Exception( "表头的标题个数要和字段长度一致!");
  25. }
  26. // 设置表头样式
  27. dataGridView.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle
  28. {
  29. Alignment = DataGridViewContentAlignment.MiddleCenter, // 中间对齐
  30. BackColor = Color.LightGray, // 表头背景色
  31. ForeColor = Color.Black, // 表头文字颜色
  32. Font = new Font( "微软雅黑", 12F, FontStyle.Bold), // 表头字体
  33. };
  34. //设置表格内容(按实体顺序依次设置名字)
  35. dataGridView.Columns.Clear();
  36. foreach ( var item in headtext)
  37. {
  38. dataGridView.Columns.Add( new DataGridViewTextBoxColumn //增加文字列
  39. {
  40. DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },
  41. HeaderText = item, //中文标题
  42. MinimumWidth = 6,
  43. Name = field[headtext.FindIndex(x=>x==item)].Name, //字段的名字 例如ID Name
  44. ReadOnly = true,
  45. SortMode = DataGridViewColumnSortMode.NotSortable,
  46. Width = 110
  47. });
  48. }
  49. //dataGridView.Columns.Add(new DataGridViewButtonColumn //增加按钮
  50. //{
  51. // DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter },
  52. // HeaderText = "操作",//中文标题
  53. // MinimumWidth = 6,
  54. // Name = "btn1",//字段的名字 例如ID Name
  55. // ReadOnly = true,
  56. // SortMode = DataGridViewColumnSortMode.NotSortable,
  57. // Width = 110
  58. //});
  59. //dataGridView.Columns[0].Width = 200; // 手动调节宽度,注意需要注释掉前面的【AutoSizeColumnsMode 自适应宽度】
  60. //dataGridView.Columns[1].Width = 200; // 手动调节宽度
  61. // dataGridView.Columns[2].Width = 80; // 手动调节宽度
  62. // dataGridView.Columns[3].Width = 80; // 手动调节宽度
  63. // dataGridView.Columns[4].Width = 80; // 手动调节宽度
  64. // dataGridView.Columns[5].Width = 80; // 手动调节宽度
  65. // dataGridView.Columns[6].Width = 300; // 手动调节宽度
  66. // 清空现有数据
  67. dataGridView.Rows.Clear();
  68. //添加数据
  69. foreach ( var item in list)
  70. {
  71. int rowIndex = dataGridView.Rows.Add();
  72. foreach ( var jtem in field)
  73. {
  74. dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = jtem.GetValue(item); //字段
  75. dataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Black;
  76. //if (jtem.Name.ToString().Equals("time"))//对特定的字段处理
  77. //{
  78. //dataGridView.Rows[rowIndex].Cells[jtem.Name.ToString()].Value = ((DateTime)(jtem.GetValue(item))).ToString("yyyy年MM月dd日");
  79. //}
  80. //dataGridView.Rows[rowIndex].Cells["btn1"].Value = "点击我";//按钮名称
  81. //移除按钮(两步)
  82. //if (false)
  83. //{
  84. // dataGridView.Rows[rowIndex].Cells["btn1"] = new DataGridViewTextBoxCell();//重新初始化
  85. // dataGridView.Rows[rowIndex].Cells["btn1"].ReadOnly = true; // 设置为只读
  86. //}
  87. }
  88. dataGridView.Rows[rowIndex].Tag = item; //绑定到Tag上方便后续调用
  89. }
  90. }
代码解读

【调用示例】 


  
  
  1. private void checkBox1_CheckedChanged(object sender, EventArgs e)
  2. {
  3. string sql = @"SELECT types,time,objects FROM BuyTable ";
  4. var entity = new Notice();
  5. //从数据库中获取列表存入list
  6. var list = entity.QueryBySQL(sql);
  7. //设置标题
  8. var headtext = new List< string>() { "购买类型", "购买时间", "购买物品" };
  9. //获取dataGridView
  10. GetDataGridView(dataGridView10,list, headtext);
  11. }
代码解读

七、高度封装的分页方法


  
  
  1. /// <summary>
  2. /// 查询数据
  3. /// </summary>
  4. private void GetData()
  5. {
  6. var list = GetList().ToList(); //假设这里是查表操作
  7. list = GetPageList(list, label7, label6, button2, button3); //【步骤一】传入相关控件实现分页
  8. List< string> title = new List< string> { { "开奖期数" }, { "开奖时间" }, { "平均值" }, { "最大值" }, { "最小值" }, { "跨度值" }, { "开奖号码" } };
  9. GetDataGridView(dataGridView1, list, title); //渲染到DataGridView中
  10. }
  11. private int currentIndex = 1; // 当前页索引
  12. private int totalPages = 0; // 总页数
  13. private List<T> GetPageList<T>(List<T> list, Label total, Label Pagedetails, Button lastpage, Button nextpage, int pagesize = 7)
  14. {
  15. lastpage.Enabled = false;
  16. nextpage.Enabled = false;
  17. var count = list.Count;
  18. totalPages = (count + pagesize - 1) / pagesize; // 计算总页数
  19. if (Pagedetails.Text.Equals( "第1页/共x页")) // 【 步骤二 winform默认设置好Pagedetails="第1页/共x页"】,此处代表第一次进入
  20. {
  21. currentIndex = 1; // 初始化当前页
  22. }
  23. else
  24. {
  25. // 创建正则表达式对象
  26. Regex regex = new Regex( @"第(\d+)页/共(\d+)页");
  27. // 尝试匹配字符串
  28. Match match = regex.Match(Pagedetails.Text);
  29. currentIndex = Convert.ToInt32(match.Groups[ 1].Value);
  30. }
  31. // 更新页数显示
  32. Pagedetails.Text = $"第{currentIndex}页/共{totalPages}页";
  33. total.Text = $"共{count}条数据";
  34. // 更新按钮状态
  35. lastpage.Enabled = currentIndex > 1; // 如果不是第一页,启用上一页按钮
  36. nextpage.Enabled = currentIndex < totalPages; // 如果不是最后一页,启用下一页按钮
  37. return list.Skip((currentIndex - 1) * pagesize).Take(pagesize).ToList(); // 获取当前页的数据
  38. }
  39. //上一页(双击按钮订阅此事件)
  40. private void button2_Click(object sender, EventArgs e)
  41. {
  42. if (currentIndex > 1) // 检查是否可以向前翻页
  43. {
  44. currentIndex--; // 当前页减一
  45. label6.Text = $"第{currentIndex}页/共{totalPages}页"; //【步骤三】更新 Pagedetails 标签
  46. GetData();
  47. }
  48. }
  49. //下一页(双击按钮订阅此事件)
  50. private void button3_Click(object sender, EventArgs e)
  51. {
  52. if (currentIndex < totalPages) // 检查是否可以向后翻页
  53. {
  54. currentIndex++; // 当前页加一
  55. label6.Text = $"第{currentIndex}页/共{totalPages}页"; //【步骤三】更新 Pagedetails 标签
  56. GetData();
  57. }
  58. }
代码解读

八、高度封装的单实体修改方法

 数据展示封装:


  
  
  1. /// <summary>
  2. /// 实体,datagridview,渲染字典=[字段:标题内容]
  3. /// </summary>
  4. /// <typeparam name="T"></typeparam>
  5. /// <param name="entity"></param>
  6. /// <param name="dataGridView1"></param>
  7. /// <param name="dict"></param>
  8. private void GetEntityUpdateList<T>(T entity, DataGridView dataGridView1, Dictionary<string, string> dict)
  9. {
  10. // 清空现有的数据
  11. dataGridView1.Rows.Clear();
  12. dataGridView1.Columns.Clear();
  13. var keys = dict.Keys.ToList();
  14. var values = dict.Values.ToList();
  15. var feildlist = typeof(T).GetProperties().Where(x => keys.Contains(x.Name)).ToList();
  16. // 添加列
  17. dataGridView1.Columns.Add( "Feild", "字段");
  18. dataGridView1.Columns.Add( "Content", "内容");
  19. // 添加行
  20. int index = 0;
  21. Dictionary< string, string> tagdict = new Dictionary< string, string>();
  22. Type type = typeof(T);
  23. object instance = Activator.CreateInstance(type);
  24. foreach ( var item in keys)
  25. {
  26. var feild = feildlist.FirstOrDefault(x => x.Name == item);
  27. dataGridView1.Rows.Add(values[index], feild?.GetValue(entity)?.ToString());
  28. type.GetProperty(keys[index])?.SetValue(instance, feild?.GetValue(entity));
  29. index++;
  30. }
  31. dataGridView1.Tag = instance;
  32. // 设置 DataGridView 为可编辑模式
  33. dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
  34. // 禁止新增行
  35. dataGridView1.AllowUserToAddRows = false;
  36. // 禁止删除行
  37. dataGridView1.AllowUserToDeleteRows = false;
  38. // 自动调整列宽
  39. dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
  40. }
代码解读

使用: 

(1)渲染datagridview(数据展示)


  
  
  1. var dict = new Dictionary< string, string>() { { "TitleHead", "标题头" }, { "TitleEnd", "标题" }, { "Href", "文章链接" }, { "Rank", "排序序号" } };
  2. GetEntityUpdateList(article,dataGridView1, dict); //article是一个实体,有TitleHead,TitleEnd等字段,且有内容
代码解读

 (2)读取datagridview


  
  
  1. var dict = new Dictionary< string, string>() { { "TitleHead", "标题头" }, { "TitleEnd", "标题" }, { "Href", "文章链接" }, { "Rank", "排序序号" } };
  2. var entity = GetInputEntityByDataGridView<Article>(dataGridView1, dict); //获取输入的实体
  3. /// <summary>
  4. /// T=要转化的实体,dataGridView控件,之前传进来的渲染字典
  5. /// </summary>
  6. /// <typeparam name="T"></typeparam>
  7. /// <param name="dataGridView1"></param>
  8. /// <param name="dict"></param>
  9. /// <returns></returns>
  10. private T GetInputEntityByDataGridView<T>(DataGridView dataGridView1, Dictionary<string, string> dict) where T:class
  11. {
  12. Dictionary< string, object> new_dict = new Dictionary< string, object>(); //存放[字段:输入内容]的字典
  13. //填充new_dict(新字典)
  14. foreach (DataGridViewRow row in dataGridView1.Rows)
  15. {
  16. var feild_chinese = row.Cells[ 0].Value;
  17. var feild_input = dict.Where(x=>x.Value.Equals(feild_chinese)).FirstOrDefault().Key;
  18. var value = row.Cells[ 1].Value;
  19. new_dict.Add(feild_input, value);
  20. }
  21. //新建一个T,反射+新字典 依次给各个字段赋值
  22. var type = typeof(T);
  23. var instance = Activator.CreateInstance(type);
  24. foreach ( var item in dict.Keys.ToList())
  25. {
  26. var cstype = type.GetProperty(item)?.PropertyType;
  27. type.GetProperty(item).SetValue(instance, Convert.ChangeType(new_dict[item], cstype));
  28. }
  29. return instance as T; //强制转化为T
  30. }
代码解读

九、小结

1.增:  建议用textbox、combobox等工具增,而不是直接datagridview新增,一来代码编写麻烦,二来输入工具不能多样化(比如说时间控件、多选框控件)。

2.删:建议每条数据加一个删除按钮,方便操作

3.改:建议选中某条数据然后将数据信息转移到textbox上,label显示“您已选中xxx数据”,然后点击button去修改相应信息(选中数据和点击按钮都能获取到对应实体)

4.查:同第2条

5.如果单纯用datagridview作增删查改,虽然能实现,但是代码复杂难以维护,而且输入条件单一,容易操作失误,不建议这么做。

;