将DataTable转换为PagedCollectionView数据,我们可以借用DataTable的GetBindableData()方法,如下:
1 DataTable dt=new DataTable(); 2 PagedCollectionView m_pagedCollectionView = new PagedCollectionView(dt.GetBindableData(new Connector())); 3 this.daDatas.ItemsSource = m_pagedCollectionView;
问题:如果直接调用GetBindableData方法的话,我们得到的所有PagedCollectionView数据将都是string类型的,为了得到数据类型的数据,我们可以自己写转换方法
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reflection; using System.Reflection.Emit; using System.Threading; using SuperMap.Web.ISDotNET6; using WaterWebGIS.MainFrame.BL; using SL40PropertyGrid; using System.ComponentModel; using Silverlight; using WaterWebGIS.QueryStatServiceProxy; using DataColumn = Silverlight.DataColumn; using DataRow = Silverlight.DataRow; using DataTable = Silverlight.DataTable; using FieldInfo = WaterWebGIS.QueryStatServiceProxy.FieldInfo; namespace WaterWebGIS.Business.DataModel { public class TypeFactory { private static List<CategoryPriorityInfo> s_categoryPriorityInfo; private static Dictionary<string, Type> s_dicTypes; private static AssemblyBuilder s_asmBuilder; private static ModuleBuilder s_modBuilder; /// <summary> /// 获取分类优先级信息 /// </summary> public static void GetCategoryPriorityInfo() { QueryStatServiceSoapClient client = (QueryStatServiceSoapClient)WaterWebGIS.Business.Utility.CreateWebServiceObject(typeof(QueryStatServiceSoapClient), "/WS/QueryService/QueryStatService.asmx"); client.GetCategoryPriorityAsync(); client.GetCategoryPriorityCompleted += new EventHandler<GetCategoryPriorityCompletedEventArgs>(client_GetCategoryPriorityCompleted); } static void client_GetCategoryPriorityCompleted(object sender, GetCategoryPriorityCompletedEventArgs e) { if (e.Error == null) { s_categoryPriorityInfo = new List<CategoryPriorityInfo>(); foreach (CategoryPriorityInfo info in e.Result) { s_categoryPriorityInfo.Add(info); } } } /// <summary> /// 将数据库中的基础数据类型转换为.Net框架中的数据类型 /// </summary> /// <param name="dbType">将数据库中保存的类型信息转换成.net中相应的类型</param> public static Type ToDotNetTypeFromDBType(string dbType) { if (dbType.ToLower() == "varchar" || dbType.ToLower() == "datetime") { return typeof(System.String); } else if (dbType.ToLower() == "int") { return typeof(System.Int32); } else if (dbType.ToLower() == "float") { return typeof(System.Double); } return typeof(DBNull); } /// <summary> /// 生成应用程序集和模块 /// </summary> private static void GenerateAssemboyAndModule() { if (s_asmBuilder == null) { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "DynamicORMapper"; AppDomain thisDomain = Thread.GetDomain(); s_asmBuilder = thisDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); s_modBuilder = s_asmBuilder.DefineDynamicModule(assemblyName.Name); } } /// <summary> /// 创建类型 /// </summary> /// <param name="modBuilder">模块生成器</param> /// <param name="layer">图层信息</param> /// <returns>类型信息</returns> private static Type CreateType(ModuleBuilder modBuilder, WaterWebGIS.QueryStatServiceProxy.GISLayer layer) { TypeBuilder typeBuilder = modBuilder.DefineType(layer.LayerNameEN, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout); CreateConstructor(typeBuilder); CreateProperties(typeBuilder, layer.FieldENlist); return typeBuilder.CreateType(); } /// <summary> /// 创建类型 /// </summary> /// <param name="modBuilder">模块生成器</param> /// <param name="table">DataTable信息</param> /// <returns>类型信息</returns> private static Type CreateType(ModuleBuilder modBuilder, DataTable table) { string tableName = "Table" + Environment.TickCount; TypeBuilder typeBuilder = modBuilder.DefineType(tableName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout); CreateConstructor(typeBuilder); CreateProperties(typeBuilder, table.Columns); return typeBuilder.CreateType(); } /// <summary> /// 创建类构造函数 /// </summary> /// <param name="typeBuilder">类型生成器</param> private static void CreateConstructor(TypeBuilder typeBuilder) { ConstructorBuilder construtor = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[0]); ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0]); ILGenerator il = construtor.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, conObj); il.Emit(OpCodes.Ret); } /// <summary> /// 创建类属性信息 /// </summary> /// <param name="typeBuilder">类型生成器</param> /// <param name="fieldInfoCollection">图层字段集合</param> private static void CreateProperties(TypeBuilder typeBuilder, ObservableCollection<WaterWebGIS.QueryStatServiceProxy.FieldInfo> fieldInfoCollection) { foreach (WaterWebGIS.QueryStatServiceProxy.FieldInfo fi in fieldInfoCollection) { if (fi.IsVisible == true) { FieldBuilder fieldBuilder = typeBuilder.DefineField("m" + fi.FieldENName, ToDotNetTypeFromDBType(fi.FieldType), FieldAttributes.Private); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(fi.FieldENName, PropertyAttributes.HasDefault, ToDotNetTypeFromDBType(fi.FieldType), null); Type[] ctorParams = new Type[] { typeof(string) }; ConstructorInfo classCtorInfo = typeof(DisplayNameAttribute).GetConstructor(ctorParams); CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { fi.FieldAlias }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); classCtorInfo = typeof(CategoryAttribute).GetConstructor(ctorParams); customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { fi.Category }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); ctorParams = new Type[] { typeof(int) }; classCtorInfo = typeof(CategoryPriorityAttribute).GetConstructor(ctorParams); customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { GetCategoryPriorityValueByCategoryName(fi.Category) }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_" + fi.FieldENName, getSetAttr, ToDotNetTypeFromDBType(fi.FieldType), Type.EmptyTypes); ILGenerator ilGenerator = getMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_" + fi.FieldENName, getSetAttr, null, new Type[] { ToDotNetTypeFromDBType(fi.FieldType) }); ilGenerator = setMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); } } } /// <summary> /// 根据分类名称获取该分类的显示优先级 /// </summary> /// <param name="categoryName">分类名称</param> /// <returns>显示优先级</returns> private static int GetCategoryPriorityValueByCategoryName(string categoryName) { if (s_categoryPriorityInfo != null) { foreach (CategoryPriorityInfo info in s_categoryPriorityInfo) { if (info.CategoryName == categoryName) { return info.Priority; } } } return int.MaxValue; } /// <summary> /// 创建类属性信息 /// </summary> /// <param name="typeBuilder">类型生成器</param> /// <param name="dataColumnCollection">DataColumnCollection</param> private static void CreateProperties(TypeBuilder typeBuilder, DataColumnCollection dataColumnCollection) { foreach (DataColumn dataColumn in dataColumnCollection) { FieldBuilder fieldBuilder = null; if (dataColumn.DataType == typeof(DateTime)) { fieldBuilder = typeBuilder.DefineField("m_" + dataColumn.ColumnName, typeof(string), FieldAttributes.Private); } else { fieldBuilder = typeBuilder.DefineField("m_" + dataColumn.ColumnName, typeof(string), FieldAttributes.Private); } PropertyBuilder propertyBuilder = null; if (dataColumn.DataType == typeof(DateTime)) { propertyBuilder = typeBuilder.DefineProperty(dataColumn.ColumnName, PropertyAttributes.HasDefault, typeof(string), null); } else { propertyBuilder = typeBuilder.DefineProperty(dataColumn.ColumnName, PropertyAttributes.HasDefault, typeof(string), null); } Type[] ctorParams = new Type[] { typeof(string) }; ConstructorInfo classCtorInfo = typeof(DisplayNameAttribute).GetConstructor(ctorParams); MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_" + dataColumn.ColumnName, getSetAttr, typeof(string), Type.EmptyTypes); ILGenerator ilGenerator = getMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_" + dataColumn.ColumnName, getSetAttr, null, new Type[] { typeof(string) }); ilGenerator = setMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); } } /// <summary> /// 根据类名获取相应的类信息 /// </summary> /// <param name="typeName">类名</param> /// <returns>类</returns> public static Type GetTypeByTypeName(string typeName) { try { if (s_dicTypes == null) { if (s_asmBuilder == null) { GenerateAssemboyAndModule(); } s_dicTypes = new Dictionary<string, Type>(); foreach (WaterWebGIS.QueryStatServiceProxy.GISLayer gisLayer in BasicGISService.GetLayers().LayerList) { try { Type type = CreateType(s_modBuilder, gisLayer); s_dicTypes.Add(gisLayer.LayerNameEN, type); } catch { } } } if (s_dicTypes.ContainsKey(typeName)) { return s_dicTypes[typeName]; } else { return null; } } catch { return null; } } public static object CreateObjectBaseOnLayerInfoAndObjectValue(WaterWebGIS.QueryStatServiceProxy.GISLayer gisLayer, SelectAction objectValue) { try { Type type = GetTypeByTypeName(gisLayer.LayerNameEN); if (type != null) { object obj = Activator.CreateInstance(type); if (obj != null) { foreach (WaterWebGIS.QueryStatServiceProxy.FieldInfo fi in gisLayer.FieldENlist) { string fieldValue = BasicGISService.GetLayers().GetValueFromRecord(objectValue.RecordSet, objectValue.Record, fi.FieldENName); object value = ConvertStringValueToSpecifyTypeValue(fieldValue, fi.FieldType); if (fi.FieldType == "datetime") { if (((DateTime)value) == DateTime.MinValue) { value = string.Empty; } else { value = value.ToString(); } } if (fi.FieldType == "float") { value = Math.Round(Convert.ToDouble(value), 3); } PropertyInfo propertyInfo = type.GetProperty(fi.FieldENName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); if (propertyInfo != null) { propertyInfo.SetValue(obj, value, null); } } } return obj; } return null; } catch { return null; } } /// <summary> /// 将字符串值转换成指定类型的值 /// </summary> /// <returns>转换后的对象值</returns> private static object ConvertStringValueToSpecifyTypeValue(string value, string dbType) { if (dbType.ToLower() == "varchar") { return value; } else if (dbType.ToLower() == "int") { int temp = 0; int.TryParse(value, out temp); return temp; } else if (dbType.ToLower() == "float") { float temp = 0; float.TryParse(value, out temp); return temp; } else if (dbType.ToLower() == "datetime") { DateTime datetime; if (DateTime.TryParse(value, out datetime)) { if (value != "0:00:00") { return datetime; } else { DateTime superMapDate = new DateTime(1899, 12, 30, 0, 0, 0); return superMapDate; } } else { return new DateTime(); } } return null; } public static Type CreateTypeBaseOnDataTable(DataTable table) { if (s_asmBuilder == null) { GenerateAssemboyAndModule(); } return CreateType(s_modBuilder, table); } /// <summary> /// 根据DataTable返回相应的对象集合 /// </summary> /// <param name="table">DataTable</param> /// <returns>对象集合</returns> public static List<object> CreateObjectCollectionBaseOnDataTable(DataTable table) { if (table == null) { throw new ArgumentNullException("table不能为空!"); } List<object> collection = new List<object>(); try { Type type = CreateTypeBaseOnDataTable(table); if (type != null) { foreach (DataRow row in table.Rows) { object obj = Activator.CreateInstance(type); if (obj != null) { foreach (DataColumn column in table.Columns) { PropertyInfo propertyInfo = type.GetProperty(column.ColumnName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); if (propertyInfo != null) { if (!string.IsNullOrEmpty(row[column.ColumnName])) { propertyInfo.SetValue(obj, ConvertStringToSpecifyType(column.DataType.FullName, row[column.ColumnName]), null); } } } } collection.Add(obj); } } return collection; } catch { return collection; } } private static object ConvertStringToSpecifyType(string typeName, string value) { switch (typeName) { case "System.Int32": //return int.Parse(value); return value; case "System.DateTime": DateTime? temp = DateTime.Parse(value); return temp.Value.ToString(); case "System.Double": //return double.Parse(value); return value; case "System.Decimal": //return Decimal.Parse(value); return value; case "System.Byte": //return byte.Parse(value); return value; case "System.String": default: return value; } } #region 除指定列转换为string类型,其他类型按所给的数据类型进行转换 //add by qzl @hn at20140424 /// <summary> /// 除指定列转换为string类型,其他类型按所给的数据类型进行转换 /// </summary> /// <param name="gisLayer">图层</param> /// <param name="objectValue">数据集</param> /// <param name="lstFiledName">转换为string类型的列</param> /// <returns></returns> public static object CreateObjectBaseOnLayerInfoAndObjectValueAndChangeText(GISLayer gisLayer, SelectAction objectValue, List<string> lstFiledName) { try { Type type = GetTypeByTypeNameToString(gisLayer.LayerNameEN, lstFiledName); if (type != null) { object obj = Activator.CreateInstance(type); if (obj != null) { foreach (FieldInfo fi in gisLayer.FieldENlist) { object value; if (lstFiledName.Contains(fi.FieldENName.ToLower())) { value ="******"; } else { string fieldValue = BasicGISService.GetLayers().GetValueFromRecord(objectValue.RecordSet, objectValue.Record, fi.FieldENName); value = ConvertStringValueToSpecifyTypeValue(fieldValue, fi.FieldType); if (fi.FieldType == "datetime") { value = ((DateTime)value) == DateTime.MinValue ? string.Empty : value.ToString(); } if (fi.FieldType == "float") { value = Math.Round(Convert.ToDouble(value), 3); } } PropertyInfo propertyInfo = type.GetProperty(fi.FieldENName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); if (propertyInfo != null) { propertyInfo.SetValue(obj, value, null); } } } return obj; } return null; } catch { return null; } } /// <summary> /// 根据类名获取相应的类信息 /// </summary> /// <param name="typeName">类名</param> /// <returns>类</returns> public static Type GetTypeByTypeNameToString(string typeName, List<string> lstFiledName) { try { if (s_dicTypes == null) { if (s_asmBuilder == null) { GenerateAssemboyAndModule(); } s_dicTypes = new Dictionary<string, Type>(); foreach (GISLayer gisLayer in BasicGISService.GetLayers().LayerList) { try { Type type = CreateTypeToString(s_modBuilder, gisLayer, lstFiledName); s_dicTypes.Add(gisLayer.LayerNameEN, type); } catch { } } } if (s_dicTypes.ContainsKey(typeName)) { return s_dicTypes[typeName]; } return null; } catch { return null; } } /// <summary> /// 创建类型 /// </summary> /// <param name="modBuilder">模块生成器</param> /// <param name="layer">图层信息</param> /// <returns>类型信息</returns> private static Type CreateTypeToString(ModuleBuilder modBuilder, GISLayer layer, List<string> lstFiledName) { TypeBuilder typeBuilder = modBuilder.DefineType(layer.LayerNameEN, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout); CreateConstructor(typeBuilder); CreatePropertiesToString(typeBuilder, layer.FieldENlist, lstFiledName); return typeBuilder.CreateType(); } /// <summary> /// 创建类属性信息 /// </summary> /// <param name="typeBuilder">类型生成器</param> /// <param name="fieldInfoCollection">图层字段集合</param> private static void CreatePropertiesToString(TypeBuilder typeBuilder, IEnumerable<FieldInfo> fieldInfoCollection, List<string> lstFiledName) { foreach (FieldInfo fi in fieldInfoCollection) { if (fi.IsVisible == true) { MethodBuilder setMethodBuilder; MethodBuilder getMethodBuilder; FieldBuilder fieldBuilder; PropertyBuilder propertyBuilder; MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; if (lstFiledName.Contains(fi.FieldENName.ToLower())) { fieldBuilder = typeBuilder.DefineField("m" + fi.FieldENName, typeof(string), FieldAttributes.Private); propertyBuilder = typeBuilder.DefineProperty(fi.FieldENName, PropertyAttributes.HasDefault, typeof(string), null); getMethodBuilder = typeBuilder.DefineMethod("get_" + fi.FieldENName, getSetAttr, typeof(string), Type.EmptyTypes); setMethodBuilder = typeBuilder.DefineMethod("set_" + fi.FieldENName, getSetAttr, null, new Type[] { typeof(string) }); } else { fieldBuilder = typeBuilder.DefineField("m" + fi.FieldENName, ToDotNetTypeFromDBType(fi.FieldType), FieldAttributes.Private); propertyBuilder = typeBuilder.DefineProperty(fi.FieldENName, PropertyAttributes.HasDefault, ToDotNetTypeFromDBType(fi.FieldType), null); getMethodBuilder = typeBuilder.DefineMethod("get_" + fi.FieldENName, getSetAttr, ToDotNetTypeFromDBType(fi.FieldType), Type.EmptyTypes); setMethodBuilder = typeBuilder.DefineMethod("set_" + fi.FieldENName, getSetAttr, null, new Type[] { ToDotNetTypeFromDBType( fi.FieldType) }); } Type[] ctorParams = new Type[] { typeof(string) }; ConstructorInfo classCtorInfo = typeof(DisplayNameAttribute).GetConstructor(ctorParams); CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { fi.FieldAlias }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); classCtorInfo = typeof(CategoryAttribute).GetConstructor(ctorParams); customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { fi.Category }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); ctorParams = new Type[] { typeof(int) }; classCtorInfo = typeof(CategoryPriorityAttribute).GetConstructor(ctorParams); customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { GetCategoryPriorityValueByCategoryName (fi.Category) }); propertyBuilder.SetCustomAttribute(customAttributeBuilder); ILGenerator ilGenerator = getMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); ilGenerator = setMethodBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); } } } //end #endregion } }