Silverlight 解决Datagrid动态绑定列问题

上次的项目中遇到这样的一个需求,需要按照考试的明细名称列出成绩信息(就是正常主从表查询的行列转化差不多的功能)。因为SL也是刚接触,所以刚拿到手真是手足无措,如果在ASP.NET中还可以在后台去自定义一个DataTable去完成。但是悲催的SL里面没有这个DataTable对象了,正常绑定的数据源是后台的一个IEnumerable类型的集合。然后在XAML界面的DataGrid的控件中自己去定义数据源和相应的列名绑定字段,前面说了由于到底明细多少是未知的,这样咱们在界面就无法设置列了。虽然后台自己组合数据源列表绑定给界面也可以,让界面自动生成也可以,但是生成的列名就是结果集的字段名称(正常都是英文的,用户我想应该是看不懂的吧。)

由于本人当时查找了不少资料,还好找到了一些解决方案,不过现在也不记得是哪个前辈给的提醒了,不过真的感谢对此有帮助的大侠们。顺便小弟在此将自己的实现方式在这里做个简短的记录,已备遇到同样问题的人也有个帮助,欢迎指出解决的不好问题。

先看下实现的效果图:

 

本例的考试明细,我就选择一个类型来演示了,如果该考试有多个明细记录,就会产生多个列了。

现在先来说下成绩的表关系吧?

主表保存作答人以及试卷的主键ID,明细表列出该试卷的每个案例明细的得分情况。1:N的关系,本例因为测试 试卷只包含了跳跳记录。

好了,基本了解了需求以及我们的结构,接下来就来实现这个功能吧。

当初我是通过数据库的3个视图集合实现的,

视图一:界面字段的主表信息(撇开明细的数据),关联字段 考试ID,作答ID

视图二:动态明细的列表信息 关联字段:作答ID

视图三:考试的案例明细 :关键字段: 考试ID

接下来我们通过加载界面查出这3个视图的集合List<Rpt_Score_M> listm, List<Rpt_Score_CataD> listd,List<View_PracticeExampleCataDetail>PracticeExampleList

然后我们自己根据上面的结果自己组合需要的XML类型的字符串

View Code
 1  #region  XmlscoreDetail集合赋值
 2         /// <summary>
 3         /// XmlscoreDetail集合赋值
 4         /// </summary>
 5         /// <param name="listm">主表集合</param>
 6         /// <param name="listd">明细表集合</param>
 7         private void SetXmlscoreDetail(List<Rpt_Score_M> listm, List<Rpt_Score_CataD> listd)
 8         {
 9             int count = 1; //序号字段
10             StringBuilder xmlscoredetail = new StringBuilder();
11             if (listm == null || listd == null) return;
12             //主数据排序
13             listm = listm.OrderByDescending(q => q.BeginTime).ToList();
14             xmlscoredetail.Append("<?xml version='1.0' encoding='utf-8' ?>");
15             xmlscoredetail.Append(" <Root>");
16             foreach (var item in listm)
17             {
18                 xmlscoredetail.Append(" <DataRow>");
19                 xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "序号", count++, "序号"));
20                 if (PracticeType == "1")
21                 {
22                     xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "练习名称", item.Subject, "练习名称"));
23                     xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "练习科目", item.SystemName, "练习科目"));
24                 }
25                 else
26                 {
27                     xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "试卷名称", item.Subject, "试卷名称"));
28                     xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "考试科目", item.SystemName, "考试科目"));
29                 }
30                 xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "班级", item.OrgName, "班级"));
31                 xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "学员学号", item.StuNO, "学员学号"));
32                 xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "学员姓名", item.FullName, "学员姓名"));
33 
34                 //赋值案例列表
35                 foreach (var temp in PracticeExampleList)
36                 {
37                     //查询当前的成绩明细是否有该案例的记录
38                     var query = from s in listd
39                                 where s.DoExampleID == item.DoExampleID
40                                 group s.Score by new { DoExampleID = s.DoExampleID, CateName = s.CateName } into _gData
41                                 select new
42                                 {
43                                     Key = _gData.Key,
44                                     Score = _gData.Sum()
45                                 };
46                     var ditem = query.Where(q => q.Key.CateName == temp.CateName && q.Key.DoExampleID == item.DoExampleID).FirstOrDefault();
47                     if (ditem != null)
48                     {
49                         xmlscoredetail.Append(string.Format("<{0}> {1}分 </{2}>", temp.CateName, ditem.Score != null ? ditem.Score.Value : 0, temp.CateName));
50                     }
51                     else
52                     {
53                         xmlscoredetail.Append(string.Format("<{0}> {1}分 </{2}>", temp.CateName, "0", temp.CateName));
54                     }
55                 }
56                 if (PracticeType == "1")
57                 {
58                     xmlscoredetail.Append(string.Format("<{0}> {1}分 </{2}>", "练习成绩", item.Scroe != null ? item.Scroe.Value : 0, "练习成绩"));
59                 }
60                 else
61                 {
62                     xmlscoredetail.Append(string.Format("<{0}> {1}分</{2}>", "考试成绩", item.Scroe != null ? item.Scroe.Value : 0, "考试成绩"));
63                 }
64                 //如果是练习增加下面字段
65                 if (PracticeType == "1")
66                 {
67                     xmlscoredetail.Append(string.Format("<{0}> {1} </{2}>", "操作日期", item.BeginTime.ToString("yyyy-MM-dd"), "操作日期"));
68                 }
69                 xmlscoredetail.Append(" </DataRow>");
70             }
71             xmlscoredetail.Append(" </Root>");
72             XmlscoreDetail = xmlscoredetail.ToString();
73         }
74         #endregion XmlscoreDetail集合赋值
View Code
#region 数据源赋值
        /// <summary>
        /// 数据源赋值
        /// </summary>
        /// <param name="xmlscoredetail">序列化的XML字符串</param>
        private void SetItems(string xmlscoredetail)
        {
            IEnumerable<IDictionary> result = GenerateData(XDocument.Parse(xmlscoredetail));
            Items = DataSourceCreator.ToDataSource(result);
            PagerContext = new PagedCollectionView(Items);
            PagerContext.PageSize = _PageSize;
        }
        #endregion 数据源赋值
View Code
 1   //根据XML类型的字符串获取字符串
 2         private static IEnumerable<IDictionary> GenerateData(XDocument xml)
 3         {
 4             var element = xml.Descendants("DataRow");
 5             foreach (XElement item in element)
 6             {
 7                 var dict = new Dictionary<object, object>();
 8                 var nodes = item.Elements();
 9                 foreach (XElement node in nodes)
10                 {
11                     dict[node.Name] = node.Value;
12                 }
13                 yield return dict;
14             }
15         }

界面的DataGrid 只要绑定生成的PagerContext 对象即可实现列名的自动绑定了。。

好了,这是我目前的实现方法,大家一起分享。欢迎大伙一起拍砖顺便指出改进!!!!

posted @ 2012-09-17 11:47  浪子の无悔  阅读(2371)  评论(0编辑  收藏  举报