一、数据填充(反射)
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 Name
ReadOnly = 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=内容)
暂未写