文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Silverlight根据Xml数据动态生成类绑定到DataGrid

Silverlight根据Xml数据动态生成类绑定到DataGrid

时间:2011-05-21  来源:J. W.

下面的代码扩展了IEnumerable接口,让此接口可以将普通的IEnumerable集合通过Emit转化成为实体类集合,这将是动态生成类的关键:

public static class DataSourceCreator    
{        
        private static readonly Regex PropertNameRegex = new Regex(@"^[A-Za-z]+[A-Za-z1-9_]*$", RegexOptions.Singleline);  
        
        public static List<object> ToDataSource(this IEnumerable<IDictionary> list)        
        {            
                IDictionary firstDict = null;            
                bool hasData = false;            
                foreach (IDictionary currentDict in list)            
                {                
                        hasData = true;                
                        firstDict = currentDict;                
                        break;            
                }            
                if (!hasData)            
                {                
                        return new List<object> { };            
                }            
                if (firstDict == null)            
                {                
                        throw new ArgumentException("IDictionary entry cannot be null");            
                }            
                Type objectType = null;            
                TypeBuilder tb = GetTypeBuilder(list.GetHashCode());            
                ConstructorBuilder constructor = tb.DefineDefaultConstructor(
                        MethodAttributes.Public | 
                        MethodAttributes.SpecialName | 
                        MethodAttributes.RTSpecialName);            
                foreach (DictionaryEntry pair in firstDict)            
                {                
                        if (PropertNameRegex.IsMatch(Convert.ToString(pair.Key), 0))                
                        {                    
                                CreateProperty(
                                        tb,                                    
                                        Convert.ToString(pair.Key),                                    
                                        pair.Value == null ? typeof(object) : pair.Value.GetType());                
                        }                
                        else                
                        {                    
                                throw new ArgumentException(@"Each key of IDictionary must be alphanumeric and start with character.");                
                        }            
                }            
                objectType = tb.CreateType();            
                return GenerateArray(objectType, list, firstDict);        
        }        
        
        private static List<object> GenerateArray(Type objectType, IEnumerable<IDictionary> list, IDictionary firstDict)        
        {            
                var itemsSource = new List<object>();            
                foreach (var currentDict in list)            
                {                
                        if (currentDict == null)                
                        {                    
                                throw new ArgumentException("IDictionary entry cannot be null");                
                        }                
                        object row = Activator.CreateInstance(objectType);                
                        foreach (DictionaryEntry pair in firstDict)                
                        {                    
                                if (currentDict.Contains(pair.Key))                    
                                {                        
                                        PropertyInfo property = objectType.GetProperty(Convert.ToString(pair.Key));
                                        property.SetValue(
                                                row,                            
                                                Convert.ChangeType(currentDict[pair.Key], property.PropertyType, null),
                                                null);                    
                                }                
                        }                
                        itemsSource.Add(row);            
                }            
                return itemsSource;        
        }        
        
        private static TypeBuilder GetTypeBuilder(int code)        
        {            
                AssemblyName an = new AssemblyName("TempAssembly" + code);            
                AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
                ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");            
                TypeBuilder tb = moduleBuilder.DefineType(
                        "TempType" + code, 
                        TypeAttributes.Public | 
                        TypeAttributes.Class | 
                        TypeAttributes.AutoClass | 
                        TypeAttributes.AnsiClass | 
                        TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, 
                        typeof(object));            
                return tb;        
        }        
        
        private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)        
        {            
                FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
                PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); 
                MethodBuilder getPropMthdBldr = tb.DefineMethod(
                        "get_" + propertyName, 
                        MethodAttributes.Public | 
                        MethodAttributes.SpecialName | 
                        MethodAttributes.HideBySig,
                        propertyType, Type.EmptyTypes);
                ILGenerator getIL = getPropMthdBldr.GetILGenerator();
                getIL.Emit(OpCodes.Ldarg_0);
                getIL.Emit(OpCodes.Ldfld, fieldBuilder);
                getIL.Emit(OpCodes.Ret);
                MethodBuilder setPropMthdBldr = tb.DefineMethod(
                        "set_" + propertyName,
                        MethodAttributes.Public | 
                        MethodAttributes.SpecialName | 
                        MethodAttributes.HideBySig,
                        null, new Type[] { propertyType });
                ILGenerator setIL = setPropMthdBldr.GetILGenerator();
                setIL.Emit(OpCodes.Ldarg_0);
                setIL.Emit(OpCodes.Ldarg_1); 
                setIL.Emit(OpCodes.Stfld, fieldBuilder);
                setIL.Emit(OpCodes.Ret);
                propertyBuilder.SetGetMethod(getPropMthdBldr);
                propertyBuilder.SetSetMethod(setPropMthdBldr);
        }    
}
 

当得到一个Xml数据源之后,用Linq To Xml或XmlReader操作此数据源,生成一个IEnumarable<IDictionary>类型的对象。其中IDictionary是一个键值对集合,这个键值对包含了一个字段的字段名和对应的值,多个这样的IDictionary(键值对集合)组成一个数据集合IEnumarable<IDictionary>。对IEnumarable<IDictionary>调用扩展方法ToDataSource获得可绑定的数据。

相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载