Silverlight实用窍门系列:9.动态生成实体类,根据XML模板使用Emit生成动态类绑定到DataGrid【附代实例源码】

简介:

  在实际项目中,我们可能会遇到用户自定义XML模板字段,根据这个模板上的字段来显示相应的字段的值到DataGrid。在这种情况下,需要使用XmlReader解析获取这个用户自定义的XML模板上有哪些字段,根据这个字段动态的生成一个实体类,之后再为此动态生成的实体类实例化,并且生成实体类集合绑定到DataGrid即可。(注意:平时我们绑定DataGrid是先在代码里面声明了实体类,实例化多个实体化类,形成实体类集合,绑定到DataGrid。可如果用户自定义XML格式的字段的时候,每次的实体类就不能为静态的了。必须为动态的才行。)

         一、首先我们准备一个XML格式的模板数据。模拟用户自定义的XML模板字段。这里的XML模板字段可以自由添改。

复制代码

  
  
< NewDataSet >
< Table TableName = ' City ' TableShowName = ' 城市 ' >
< Column Name = ' CityName ' ShowName = ' 城市名称 ' />
< Column Name = ' CityTel ' ShowName = ' 城市区号 ' />
< Column Name = ' CityCounty ' ShowName = ' 城市所属国家 ' />
</ Table >
< Table TableName = ' User ' TableShowName = ' 用户 ' >
< Column Name = ' UserName ' ShowName = ' 用户名 ' />
< Column Name = ' UserPwd ' ShowName = ' 用户密码 ' />
< Column Name = ' UserTel ' ShowName = ' 用户电话 ' />
< Column Name = ' UserEmail ' ShowName = ' 用户邮箱 ' />
</ Table >
</ NewDataSet >
复制代码

        再声明一个实体类来保存字段的Name和显示名称ShowName,并且把这些字段存放到List<>中去。

复制代码

  
  
/// <summary>
/// 存放动态表格的字段
/// </summary>
public class GridClass
{
private string _ShowName;
private string _Name;
/// <summary>
/// 显示名称
/// </summary>
public string ShowName
{
get { return _ShowName; }
set { _ShowName = value; }
}
/// <summary>
/// 字段名称
/// </summary>
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
复制代码

        二、准备好数据之后,我们开始解析这个XML文档,并且根据此XML文档生成两个动态Tabel实体类。这里我们首先贴出关键代码,根据代码来解读:

复制代码

  
  
List < GridClass > gridClassList = new List < GridClass > (); // 声明一个GridClass实体类的集合。
using (XmlReader xmlRead = XmlReader.Create( new StringReader(XMLStr)))
{
xmlRead.Read();
while (xmlRead.Read())
{
// 获取到一个TABLE,然后转化为一个动态的实体类。
gridClassList.Clear(); // 循环读取Tabel元素的时候,清空GridClass实体类集合。
xmlRead.ReadToFollowing( " Table " ); // 读取Table的显示名称和Tabel的名称。
string TableShowName = xmlRead.GetAttribute( " TableShowName " );
string TableName = xmlRead.GetAttribute( " TableName " );
try
{
using (XmlReader xReader2 = xmlRead.ReadSubtree()) // 将此Tabel读取为一个子XmlReader以供下一步使用。
{
while (xReader2.ReadToFollowing( " Column " ))
{
// 循环读取Column元素,然后获取到Tabel的字段的显示名称和字段名称。并且添加到gridClassList
string ShowName = xReader2.GetAttribute( " ShowName " );
string Name = xReader2.GetAttribute( " Name " );
GridClass gclass
= new GridClass() { ShowName = ShowName, Name = Name };
gridClassList.Add(gclass);
}
// 声明一个Dictionary<string, string>的List<>集合
List < Dictionary < string , string >> dicList = new List < Dictionary < string , string >> ();
// 声明一个Dictionary<string, string>实体,然后为此实体赋值列名为读取Column元素得到的字段名称
Dictionary < string , string > dic = new Dictionary < string , string > ();
for ( int j = 0 ; j < gridClassList.Count; j ++ )
{
dic[gridClassList[j].Name]
= " -- " + gridClassList[j].Name + " -- " ;
}
dicList.Add(dic);
// 动态生成一个DataGrid,并且绑定数据源
DataGrid dgrid = new DataGrid();
dgrid.HorizontalAlignment
= HorizontalAlignment.Left;
dgrid.VerticalAlignment
= VerticalAlignment.Top;
dgrid.Margin
= new Thickness( 20 , 5 , 0 , 0 );
dgrid.Width
= 960 ;
dgrid.Name
= TableName;
dgrid.ItemsSource
= GetEnumerable(dicList).ToDataSource();

this .mainPanel.Children.Add(dgrid);
}
}
catch (Exception ex)
{ }
}
}
}
复制代码

        这里解析出关键的字段值,然后动态生成DataGrid,并且绑定了数据库。这些操作是不是很熟悉?几乎和原来绑定数据差不多?关键在以下几句:

复制代码

  
  
// 声明一个Dictionary<string, string>的List<>集合
List < Dictionary < string , string >> dicList = new List < Dictionary < string , string >> ();
// 声明一个Dictionary<string, string>实体,然后为此实体赋值列名为读取Column元素得到的字段名称
Dictionary < string , string > dic = new Dictionary < string , string > ();
for ( int j = 0 ; j < gridClassList.Count; j ++ )
{
dic[gridClassList[j].Name]
= " -- " + gridClassList[j].Name + " -- " ;
}
dicList.Add(dic);
复制代码

        通过这段代码我们得到了一个 List<Dictionary<string, string>>格式的Dictionary<string, string>集合。这里Dictionary的Key值,即为一列字段名,Value为该列的具体值,那么一个Dictionary[0],Dictionary[1],Dictionary[2],Dictionary[3],Dictionary[4],Dictionary[5]即为一行有字段名的数据,整个List<Dictionary>就是一个多行有字段名的数据,这就相当于一个类似于DataTabel的表了。

        三、当然更关键的下一句:dgrid.ItemsSource = GetEnumerable(dicList).ToDataSource();这句话肯定是得到了一个类似于List<object>对象集的东西,才能够绑定到ItemSource属性上来。具体是如何得到这个数据集的呢?在这里暂且先卖一个关子,请看下面源码:

复制代码

  
  
public IEnumerable < IDictionary > GetEnumerable(List < Dictionary < string , string >> SourceList)
{
for ( int i = 0 ; i < SourceList.Count; i ++ )
{
var dict
= new Dictionary < string , string > ();
dict
= SourceList[i];
yield return dict;
}
}
复制代码

        这个函数是将List<Dictionary<string, string>>的数据,通过遍历的方式读取出来,使用yield return关键字来获取到IEnumerable<IDictionary>类型的返回值。在这里取到一个数据格式转换的作用,我们看下面这个隐藏起来的类。这个类是国外友人Vladimir Bodurov 编写的,它扩展了IEnumerable接口,让此接口可以将普通的IEnumerable集合通过Emit转化成为实体类集合。想必现在我们再来看dgrid.ItemsSource = GetEnumerable(dicList).ToDataSource();这句代码就很清晰了吧,在这里我们就实现了动态创建类的过程。

DataSourceCreator.cs

        本文实例源码采用VS2010+Silverlight 4.0编写,点击 SLReadDanamicClassToDataGrid.rar 下载此源码。

       



    本文转自程兴亮博客园博客,原文链接:http://www.cnblogs.com/chengxingliang/archive/2011/02/21/1960146.html,如需转载请自行联系原作者

相关文章
|
8月前
|
XML Java uml
spring 源码解析——第一篇(ioc xml方式)
spring 源码解析——第一篇(ioc xml方式)
66 0
|
8月前
|
XML Java Maven
第1次Spring源码学习之@Bean、@Configuration、xml、分析
第1次Spring源码学习之@Bean、@Configuration、xml、分析
76 0
|
3月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
96 0
|
7月前
|
XML Java Maven
Spring中AOP最简单实例-XML形式
Spring中AOP最简单实例-XML形式
31 0
|
8月前
|
XML 移动开发 前端开发
基于若依的ruoyi-nbcio流程管理系统里修正仿钉钉流程部门主管与多实例转xml的bug
基于若依的ruoyi-nbcio流程管理系统里修正仿钉钉流程部门主管与多实例转xml的bug
64 1
|
XML Java 数据库连接
【spring源码系列-03】xml配置文件启动spring时refresh的前置工作
【spring源码系列-03】xml配置文件启动spring时refresh的前置工作
122 0
|
XML Java 数据格式
Spring高手之路16——解析XML配置映射为BeanDefinition的源码
本文提供了深入Spring源码的透彻解析,从XML配置文件的加载开始,步入了Spring的内部世界。通过细致剖析setConfigLocations、refresh和loadBeanDefinitions等方法的实现,揭示了Bean从定义到注册的整个生命周期。
152 1
Spring高手之路16——解析XML配置映射为BeanDefinition的源码
|
8月前
|
XML JavaScript API
框架选修课之dom4j解析xml字符串实例
框架选修课之dom4j解析xml字符串实例
123 1
|
8月前
|
XML Java 数据格式
Spring5源码(17)-Spring解析xml默认命名空间
Spring5源码(17)-Spring解析xml默认命名空间
48 0
|
8月前
|
XML JavaScript Java
Spring5源码(16)-Spring将Xml文件解析为Document对象
Spring5源码(16)-Spring将Xml文件解析为Document对象
70 0

相关课程

更多