在C#中的WinForm开发中,大家经常用到DataGridView表格数据展示控件,由于此控件绑定数据列时只能绑定一层,不支持“属性.属性”的这种两层及多层绑定方式(而在C#的Web开发中用到的GridView控件尽可以使用这种“属性.属性”的这种绑定方式,毕竟C#属于.NET语言,Web的开发更加强大),所以如果遇到实体类的结构中的属性类型又属于实体类的类型时,就要特别注意,不能直接使用“属性.属性”进行绑定,这样的绑定只能显示出第一个属性的名称,而不能显示出其包含的属性值。然而我们可以在数据绑定前进行转换,如下面的代码思路。此时对于其中“学生姓名”列的属性DataPropertyName使用StudentName进行赋值。
上面的图中数据来自于三个表,其中“学员姓名”来自于“Student”数据表; “科目”来自于“Subject”数据表; “成绩”、“考试时间”来自于“Result”数据表。
public class Result
{
private Student student;
public Student Student
{
get { return student; }
set { student = value; }
}
public string SubjectName { get; set; }
public int StudentResult { get; set; }
public DateTime ExamDate { get; set; }
}
public class Student
{
public int StudentNo{set;get;}
private string studentName;
public string StudentName
{
get { return studentName; }
set { studentName = value; }
}
public string Phone { set; get; }
public string Address { set; get; }
}
第一种处理方案为:可以使用linq转换下,把嵌套的属性提升到顶层,即将表达式“属性.属性”处理为“属性”方式进行显示绑定到DataGridView控件上。关键代码如下所示:
List<Result> results = ResultManager.ReviewStudentResult(strSubjectNo, strStuName);
var changeResults = results.Select(x => new {x.ExamDate,x.StudentResult, 子对象_属性=x.Student.StudentName,x.SubjectName });
this.dgvResult.DataSource = changeResults.ToList();
将DataGridView的该列DataPropertyName属性的值为"子对象_属性"即可。
第二种处理方案为:在绑定数据时仍然使用Student属性列,此时DataGridView中“学生姓名”列的属性DataPropertyName使用Student属性进行赋值。,不过需要在DataGridView中的事件CellFormatting中进行单元格数据的二次处理,代码如下:
private void dgvResult_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex==0 && e.Value != null)
{
if (e.Value is Student)
{
e.Value = (e.Value as Student).StudentName;
}
}
}
DataGridView的数据绑定的关键代码:
List<Result> results = ResultManager.ReviewStudentResult(strSubjectNo, strStuName);
this.dgvResult.DataSource = results;
文中的这2种方案的示例源码如下: (提取码:04a6)