先来写一个Student类
1 public class Student
2
3 {
4
5 public int StudentNo { get; set; }
6
7 public string StudentName { get; set; }
8
9 public string Address { get; set; }
10
11 public int GradeId { get; set; }
12
13
14
15 public string Gender { get; set; }
16
17 public string LoginPwd { get; set; }
18
19 public DateTime Birthday { get; set; }
20
21 public string Email { get; set; }
22
23 public string Phone { get; set; }
24
25
26
27 }
然后有一个Result类
public class Result
{
public Student Student { get; set; }
public Subject Subject { get; set; }
public DateTime ExamDate { get; set; }
public int StudentResult { get; set; }
}
首先,我们看到的这三个类中,Result类中有Student和Subject的对象, 当我们通过List<Result>拿到符合条件的数据后,就可以将List<Result>中的数据绑定到DataGridView上了,但是DataGridView控件上绑定result时学生姓名和科目名称的数据没有出来
现在我们有四种解决方法:
方法一:通过重写ToString()方法的方案解决
01.如果能保证在实体Result中的Student属性到时候在界面上行只显示Student中的一个属性,例如StudentName,那么我们重写Student的ToString()方法来达到目的。
重写代码如下:
public override string ToString()
{
return StudentName;
}
这时候只需要设置DataPropertyName的值为Student,即可,因为设置了Student后,会自动调用它的ToString()方法将StudentName返回。
但是,该方法的确定是:返回值,只能用一个属性。
方法二:
添加辅助列
注意事项:01.该方法的学生姓名列和科目列的DataPropertyName不能给值
02.辅助列要隐藏
03.根据辅助列的值去查询数据库中对应的名称
所以:
Result类
public class Result
{
public int StudentNo { get; set; }
public int SubjectId { get; set; }
public DateTime ExamDate { get; set; }
public int StudentResult { get; set; }
}
我们可以通过StudentNo 和SubjectId来查询Student表中的StudentName和Subject表中的SubjectName的列,.这时候只需要设置DataPropertyName的值为StudentNo,SubjectId
方法三:
使用DataGridViewComboBoxColumn
代码如下:
DataGridViewComboBoxColumn cbo = (DataGridViewComboBoxColumn)this.dataGridView1.Columns["StudentNo"];
cbo.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
cbo.DataSource = sb.ShoeTimeTwo();
cbo.DisplayMember = "StudentName";
cbo.ValueMember = "StudentNo";
该方法的学生姓名列和科目列分别给值为Studentno和Subjectid
方式四:实体扩张类
我们都知道 在Result类中有Student表中的StudentName和Subject表的SubjectName,所以我们可以将这两个属性重新写一个类(StudentResult),让该类集成Result类,我们知道继承的特性子类可以集成父类。
所以我们使用该类(StudentResult),数据绑定直接用StudentName,SubjectName
其次,我们还可以:方案二:在DataGridView控件中,通过在CellFormatting事件中通过反射获取。
01.当数据无法显示在DataGirdView中的时候,其实通过断点调试法,我们发现数据已经在集合中已经有了。只是无法显示在DataGridView控件中而已。那么我们在DataGridView控件的CellFormatting事件中编码实现。故名思意,就是在列加载的时候出发的时间,又称为重写该事件。
代码如下:
//找到绑定字段中带下划线的列
if ((dataGridView1.Rows[e.RowIndex].DataBoundItem != null) &&
(dataGridView1.Columns[e.ColumnIndex].DataPropertyName.Contains(".")))
{
//用split方法将其分割成一个数组
string[] names = dataGridView1.Columns[e.ColumnIndex].DataPropertyName.Split('.');
object obj = dataGridView1.Rows[e.RowIndex].DataBoundItem;//获取到当前记录绑定的类型
for (int i = 0; i < names.Count(); ++i)
{
try
{
//通过反射的方式获取当前列的属性值,如StudentName
//第一次循环到Student,第二次拿到的是StudentName
var result = obj.GetType().GetProperty(names[i]).GetValue(obj, null);
obj = result;
e.Value = result.ToString();//拿到对应的值
}
catch (Exception)
{
return;
throw;
}
}
}
02.这时候要给DataPropertyName属性赋值为Student.StudentName
解析:这种方式可以处理Student中多列出现在DataGridView中的情况,是比较好的解决方案。而且这样解决方案可以处理Result中引入多个外部实体的属性的情况。